⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 error.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-1999  Brian Bruns * Copyright (C) 2003, 2004, 2005, 2006, 2007  Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif /* HAVE_CONFIG_H */#include <stdarg.h>#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#include <assert.h>#include "tdsodbc.h"#include "tdsstring.h"#include "replacements.h"#if HAVE_ODBCSS_H#include <odbcss.h>#endif#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: error.c,v 1.49 2007/10/16 15:12:21 freddy77 Exp $");static void odbc_errs_pop(struct _sql_errors *errs);static const char *odbc_get_msg(const char *sqlstate);static void odbc_get_v2state(const char *sqlstate, char *dest_state);static void sqlstate2to3(char *state);struct s_SqlMsgMap{	const char *msg;	char sqlstate[6];};/* This list contains both v2 and v3 messages */#define ODBCERR(s3,msg) { msg, s3 }static const struct s_SqlMsgMap SqlMsgMap[] = {	ODBCERR("IM007", "No data source or driver specified"),	ODBCERR("01000", "Warning"),	ODBCERR("01002", "Disconnect error"),	ODBCERR("01004", "Data truncated"),	ODBCERR("01504", "The UPDATE or DELETE statement does not include a WHERE clause"),	ODBCERR("01508", "Statement disqualified for blocking"),	ODBCERR("01S00", "Invalid connection string attribute"),	ODBCERR("01S01", "Error in row"),	ODBCERR("01S02", "Option value changed"),	ODBCERR("01S06", "Attempt to fetch before the result set returned the first rowset"),	ODBCERR("01S07", "Fractional truncation"),	ODBCERR("07001", "Wrong number of parameters"),	ODBCERR("07002", "Too many columns"),	ODBCERR("07005", "The statement did not return a result set"),	ODBCERR("07006", "Invalid conversion"),	ODBCERR("07009", "Invalid descriptor index"),	ODBCERR("08001", "Unable to connect to data source"),	ODBCERR("08002", "Connection in use"),	ODBCERR("08003", "Connection is closed"),	ODBCERR("08004", "The application server rejected establishment of the connection"),	ODBCERR("08007", "Connection failure during transaction"),	ODBCERR("08S01", "Communication link failure"),	ODBCERR("0F001", "The LOB token variable does not currently represent any value"),	ODBCERR("21S01", "Insert value list does not match column list"),	ODBCERR("22001", "String data right truncation"),	ODBCERR("22002", "Invalid output or indicator buffer specified"),	ODBCERR("22003", "Numeric value out of range"),	ODBCERR("22005", "Error in assignment"),	ODBCERR("22007", "Invalid datetime format"),	ODBCERR("22008", "Datetime field overflow"),	ODBCERR("22011", "A substring error occurred"),	ODBCERR("22012", "Division by zero is invalid"),	ODBCERR("22015", "Interval field overflow"),	ODBCERR("22018", "Invalid character value for cast specification"),	ODBCERR("22019", "Invalid escape character"),	ODBCERR("22025", "Invalid escape sequence"),	ODBCERR("22026", "String data, length mismatch"),	ODBCERR("23000", "Integrity constraint violation"),	ODBCERR("24000", "Invalid cursor state"),	ODBCERR("24504", "The cursor identified in the UPDATE, DELETE, SET, or GET statement is not positioned on a row"),	ODBCERR("25501", "Invalid transaction state"),	ODBCERR("28000", "Invalid authorization specification"),	ODBCERR("34000", "Invalid cursor name"),	ODBCERR("37000", "Invalid SQL syntax"),	ODBCERR("40001", "Serialization failure"),	ODBCERR("40003", "Statement completion unknown"),	ODBCERR("42000", "Syntax error or access violation"),	ODBCERR("42601", "PARMLIST syntax error"),	ODBCERR("42818", "The operands of an operator or function are not compatible"),	ODBCERR("42895", "The value of a host variable in the EXECUTE or OPEN statement cannot be used because of its data type"),	ODBCERR("428A1", "Unable to access a file referenced by a host file variable"),	ODBCERR("44000", "Integrity constraint violation"),	ODBCERR("54028", "The maximum number of concurrent LOB handles has been reached"),	ODBCERR("56084", "LOB data is not supported in DRDA"),	ODBCERR("58004", "Unexpected system failure"),	ODBCERR("HY000", "General driver error"),	ODBCERR("HY001", "Memory allocation failure"),	ODBCERR("HY002", "Invalid column number"),	ODBCERR("HY003", "Program type out of range"),	ODBCERR("HY004", "Invalid data type"),	ODBCERR("HY007", "Associated statement is not prepared"),	ODBCERR("HY008", "Operation was cancelled"),	ODBCERR("HY009", "Invalid argument value"),	ODBCERR("HY010", "Function sequence error"),	ODBCERR("HY011", "Operation invalid at this time"),	ODBCERR("HY012", "Invalid transaction code"),	ODBCERR("HY013", "Unexpected memory handling error"),	ODBCERR("HY014", "No more handles"),	ODBCERR("HY016", "Cannot modify an implementation row descriptor"),	ODBCERR("HY017", "Invalid use of an automatically allocated descriptor handle"),	ODBCERR("HY018", "Server declined cancel request"),	ODBCERR("HY021", "Inconsistent descriptor information"),	ODBCERR("HY024", "Invalid attribute value"),	ODBCERR("HY090", "Invalid string or buffer length"),	ODBCERR("HY091", "Descriptor type out of range"),	ODBCERR("HY092", "Invalid option"),	ODBCERR("HY093", "Invalid parameter number"),	ODBCERR("HY094", "Invalid scale value"),	ODBCERR("HY096", "Information type out of range"),	ODBCERR("HY097", "Column type out of range"),	ODBCERR("HY098", "Scope type out of range"),	ODBCERR("HY099", "Nullable type out of range"),	ODBCERR("HY100", "Uniqueness option type out of range"),	ODBCERR("HY101", "Accuracy option type out of range"),	ODBCERR("HY103", "Direction option out of range"),	ODBCERR("HY104", "Invalid precision value"),	ODBCERR("HY105", "Invalid parameter type"),	ODBCERR("HY106", "Fetch type out of range"),	ODBCERR("HY107", "Row value out of range"),	ODBCERR("HY108", "Concurrency option out of range"),	ODBCERR("HY109", "Invalid cursor position"),	ODBCERR("HY110", "Invalid driver completion"),	ODBCERR("HY111", "Invalid bookmark value"),	ODBCERR("HY501", "Invalid data source name"),	ODBCERR("HY503", "Invalid file name length"),	ODBCERR("HY506", "Error closing a file"),	ODBCERR("HY509", "Error deleting a file"),	ODBCERR("HYC00", "Driver not capable"),	ODBCERR("HYT00", "Timeout expired"),	ODBCERR("HYT01", "Connection timeout expired"),	ODBCERR("S0001", "Database object already exists"),	ODBCERR("S0002", "Database object does not exist"),	ODBCERR("S0011", "Index already exists"),	ODBCERR("S0012", "Index not found"),	ODBCERR("S0021", "Column already exists"),	ODBCERR("S0022", "Column not found"),	ODBCERR("", NULL)};#undef ODBCERRstruct s_v3to2map{	char v3[6];	char v2[6];};/* Map a v3 SQLSTATE to a v2 */static const struct s_v3to2map v3to2map[] = {	{"01001", "01S03"},	{"01001", "01S04"},	{"HY019", "22003"},	{"22007", "22008"},	{"22018", "22005"},	{"07005", "24000"},	{"42000", "37000"},	{"HY018", "70100"},	{"42S01", "S0001"},	{"42S02", "S0002"},	{"42S11", "S0011"},	{"42S12", "S0012"},	{"42S21", "S0021"},	{"42S22", "S0022"},	{"42S23", "S0023"},	{"HY000", "S1000"},	{"HY001", "S1001"},	{"07009", "S1002"},	{"HY003", "S1003"},	{"HY004", "S1004"},	{"HY008", "S1008"},	{"HY009", "S1009"},	{"HY024", "S1009"},	{"HY007", "S1010"},	{"HY010", "S1010"},	{"HY011", "S1011"},	{"HY012", "S1012"},	{"HY090", "S1090"},	{"HY091", "S1091"},	{"HY092", "S1092"},/*	{"07009", "S1093"}, */	{"HY096", "S1096"},	{"HY097", "S1097"},	{"HY098", "S1098"},	{"HY099", "S1099"},	{"HY100", "S1100"},	{"HY101", "S1101"},	{"HY103", "S1103"},	{"HY104", "S1104"},	{"HY105", "S1105"},	{"HY106", "S1106"},	{"HY107", "S1107"},	{"HY108", "S1108"},	{"HY109", "S1109"},	{"HY110", "S1110"},	{"HY111", "S1111"},	{"HYC00", "S1C00"},	{"HYT00", "S1T00"},	{"08001", "S1000"},	{"IM007", "S1000"},	{"", ""}};/*  * ODBC messages must be sorted by importance * 1. Errors regarding the status of a transaction * 2. Other errors (level ordered) * 3. No-Data messages with a state class of 02 ?? * 4. Warning * 5. Informational */static voidrank_errors(struct _sql_errors *errs){	int settled, current, best;	struct _sql_error swapbuf;	char istrans;	if (errs->ranked == 0 && errs->num_errors > 1) {		/* Find the highest of all unranked errors until there are none left */		for (settled = 0; settled < errs->num_errors; settled++) {			best = -1;			for (current = settled; current < errs->num_errors; current++) {				istrans = 0;				switch (errs->errs[current].native) {				case 1205:				case 1211:				case 2625:				case 3309:				case 7112:				case 266:				case 277:				case 611:				case 628:				case 3902:				case 3903:				case 3906:				case 3908:				case 6401:					istrans = 1;					break;				}				if (istrans == 0) {					if (strcmp(errs->errs[current].state3,"25000") == 0)						istrans = 1;					else if (strcmp(errs->errs[current].state3,"S1012") == 0)						istrans = 1;					else if (strcmp(errs->errs[current].state3,"08007") == 0)						istrans = 1;				}				/* Transaction errors are always best */				if (istrans == 1 && errs->errs[current].msgstate >= 10)	{					best = current;					break;				}				if (best == -1)					best = current;				/* Non-terminating comparisons only below this point */				if (errs->errs[current].msgstate > errs->errs[best].msgstate)					best = current;			}			/* swap settled position with best */			if (best != settled) {				swapbuf = errs->errs[settled];				errs->errs[settled] = errs->errs[best];				errs->errs[best] = swapbuf;			}		}	}	errs->ranked = 1;}static const char *odbc_get_msg(const char *sqlstate){	const struct s_SqlMsgMap *pmap = SqlMsgMap;	/* TODO set flag and use pointers (no strdup) ?? */	while (pmap->msg) {		if (!strcasecmp(sqlstate, pmap->sqlstate)) {			return strdup(pmap->msg);		}		++pmap;	}	return strdup("");}static voidodbc_get_v2state(const char *sqlstate, char *dest_state){	const struct s_v3to2map *pmap = v3to2map;	while (pmap->v3[0]) {		if (!strcasecmp(pmap->v3, sqlstate)) {			tds_strlcpy(dest_state, pmap->v2, 6);			return;		}		++pmap;	}	/* return the original if a v2 state is not found */	tds_strlcpy(dest_state, sqlstate, 6);}voidodbc_errs_reset(struct _sql_errors *errs){	int i;	if (errs->errs) {		for (i = 0; i < errs->num_errors; ++i) {			/* TODO see flags */			free((char *) errs->errs[i].msg);			free(errs->errs[i].server);		}		TDS_ZERO_FREE(errs->errs);		errs->num_errors = 0;	}	errs->lastrc = SQL_SUCCESS;	errs->ranked = 0;	assert(errs->num_errors == 0);}/** Remove first element */static voidodbc_errs_pop(struct _sql_errors *errs){	if (!errs || !errs->errs || errs->num_errors <= 0)		return;	if (errs->num_errors == 1) {		odbc_errs_reset(errs);		return;	}	/* TODO see flags */	free((char *) errs->errs[0].msg);	free(errs->errs[0].server);	--errs->num_errors;	memmove(&(errs->errs[0]), &(errs->errs[1]), errs->num_errors * sizeof(errs->errs[0]));}voidodbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg){	struct _sql_error *p;	int n = errs->num_errors;	assert(sqlstate);	if (errs->errs)		p = (struct _sql_error *) realloc(errs->errs, sizeof(struct _sql_error) * (n + 1));	else		p = (struct _sql_error *) malloc(sizeof(struct _sql_error));	if (!p)		return;	errs->errs = p;	memset(&errs->errs[n], 0, sizeof(struct _sql_error));	errs->errs[n].native = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -