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

📄 odbc.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (pibScale) {		if (drec->sql_desc_type == SQL_NUMERIC || drec->sql_desc_type == SQL_DECIMAL		    || drec->sql_desc_type == SQL_DATETIME || drec->sql_desc_type == SQL_FLOAT) {			*pibScale = drec->sql_desc_scale;		} else {			/* TODO test setting desc directly, SQLDescribeCol return just descriptor data ?? */			*pibScale = 0;		}	}	if (pfNullable) {		*pfNullable = drec->sql_desc_nullable;	}	ODBC_RETURN_(stmt);}static SQLRETURN_SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax,		 SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc){	TDS_DESC *ird;	struct _drecord *drec;	SQLRETURN result = SQL_SUCCESS;	INIT_HSTMT;	tdsdump_log(TDS_DBG_FUNC, "_SQLColAttribute(%p, %u, %u, %p, %d, %p, %p)\n", 			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);	ird = stmt->ird;#define COUT(src) result = odbc_set_string(rgbDesc, cbDescMax, pcbDesc, src ? src : "", -1);#define SOUT(src) result = odbc_set_string(rgbDesc, cbDescMax, pcbDesc, tds_dstr_cstr(&src), -1);/* SQLColAttribute returns always attributes using SQLINTEGER */#if ENABLE_EXTRA_CHECKS#define IOUT(type, src) do { \	/* trick warning if type wrong */ \	type *p_test = &src; p_test = p_test; \	*pfDesc = src; } while(0)#else#define IOUT(type, src) *pfDesc = src#endif	/* dont check column index for these */	switch (fDescType) {#if SQL_COLUMN_COUNT != SQL_DESC_COUNT	case SQL_COLUMN_COUNT:#endif	case SQL_DESC_COUNT:		IOUT(SQLSMALLINT, ird->header.sql_desc_count);		ODBC_RETURN(stmt, SQL_SUCCESS);		break;	}	if (!ird->header.sql_desc_count) {		odbc_errs_add(&stmt->errs, "07005", NULL);		ODBC_RETURN(stmt, SQL_ERROR);	}	if (icol <= 0 || icol > ird->header.sql_desc_count) {		odbc_errs_add(&stmt->errs, "07009", "Column out of range");		ODBC_RETURN(stmt, SQL_ERROR);	}	drec = &ird->records[icol - 1];	tdsdump_log(TDS_DBG_INFO1, "odbc:SQLColAttribute: fDescType is %d\n", fDescType);	switch (fDescType) {	case SQL_DESC_AUTO_UNIQUE_VALUE:		IOUT(SQLUINTEGER, drec->sql_desc_auto_unique_value);		break;	case SQL_DESC_BASE_COLUMN_NAME:		SOUT(drec->sql_desc_base_column_name);		break;	case SQL_DESC_BASE_TABLE_NAME:		SOUT(drec->sql_desc_base_table_name);		break;	case SQL_DESC_CASE_SENSITIVE:		IOUT(SQLINTEGER, drec->sql_desc_case_sensitive);		break;	case SQL_DESC_CATALOG_NAME:		SOUT(drec->sql_desc_catalog_name);		break;#if SQL_COLUMN_TYPE != SQL_DESC_CONCISE_TYPE	case SQL_COLUMN_TYPE:		/* special case, get ODBC 2 type, not ODBC 3 SQL_DESC_CONCISE_TYPE (different for datetime) */		if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {			IOUT(SQLSMALLINT, drec->sql_desc_concise_type);			break;		}		/* get type and convert it to ODBC 2 type */		{			SQLSMALLINT type = drec->sql_desc_concise_type;			switch (type) {			case SQL_TYPE_DATE:				type = SQL_DATE;				break;			case SQL_TYPE_TIME:				type = SQL_TIME;				break;			case SQL_TYPE_TIMESTAMP:				type = SQL_TIMESTAMP;				break;			}			IOUT(SQLSMALLINT, type);		}		break;#else	case SQL_DESC_CONCISE_TYPE:		IOUT(SQLSMALLINT, drec->sql_desc_concise_type);		break;#endif	case SQL_DESC_DISPLAY_SIZE:		IOUT(SQLLEN, drec->sql_desc_display_size);		break;	case SQL_DESC_FIXED_PREC_SCALE:		IOUT(SQLSMALLINT, drec->sql_desc_fixed_prec_scale);		break;	case SQL_DESC_LABEL:		SOUT(drec->sql_desc_label);		break;		/* FIXME special cases for SQL_COLUMN_LENGTH */	case SQL_COLUMN_LENGTH:		IOUT(SQLLEN, drec->sql_desc_octet_length);		break;	case SQL_DESC_LENGTH:		IOUT(SQLULEN, drec->sql_desc_length);		break;	case SQL_DESC_LITERAL_PREFIX:		COUT(drec->sql_desc_literal_prefix);		break;	case SQL_DESC_LITERAL_SUFFIX:		COUT(drec->sql_desc_literal_suffix);		break;	case SQL_DESC_LOCAL_TYPE_NAME:		SOUT(drec->sql_desc_local_type_name);		break;#if SQL_COLUMN_NAME != SQL_DESC_NAME	case SQL_COLUMN_NAME:#endif	case SQL_DESC_NAME:		SOUT(drec->sql_desc_name);		break;#if SQL_COLUMN_NULLABLE != SQL_DESC_NULLABLE	case SQL_COLUMN_NULLABLE:#endif	case SQL_DESC_NULLABLE:		IOUT(SQLSMALLINT, drec->sql_desc_nullable);		break;	case SQL_DESC_NUM_PREC_RADIX:		IOUT(SQLINTEGER, drec->sql_desc_num_prec_radix);		break;	case SQL_DESC_OCTET_LENGTH:		IOUT(SQLLEN, drec->sql_desc_octet_length);		break;		/* FIXME special cases for SQL_COLUMN_PRECISION */	case SQL_COLUMN_PRECISION:		if (drec->sql_desc_concise_type == SQL_REAL) {			*pfDesc = 7;			break;		}		if (drec->sql_desc_concise_type == SQL_DOUBLE) {			*pfDesc = 15;			break;		}		if (drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP) {			*pfDesc = drec->sql_desc_precision ? 23 : 16;			break;		}	case SQL_DESC_PRECISION:	/* this section may be wrong */		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)			IOUT(SQLSMALLINT, drec->sql_desc_precision);		else			*pfDesc = drec->sql_desc_length;		break;		/* FIXME special cases for SQL_COLUMN_SCALE */	case SQL_COLUMN_SCALE:	case SQL_DESC_SCALE:	/* this section may be wrong */		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP || drec->sql_desc_concise_type == SQL_FLOAT)			IOUT(SQLSMALLINT, drec->sql_desc_scale);		else			*pfDesc = 0;		break;	case SQL_DESC_SCHEMA_NAME:		SOUT(drec->sql_desc_schema_name);		break;	case SQL_DESC_SEARCHABLE:		IOUT(SQLSMALLINT, drec->sql_desc_searchable);		break;	case SQL_DESC_TABLE_NAME:		SOUT(drec->sql_desc_table_name);		break;	case SQL_DESC_TYPE:		IOUT(SQLSMALLINT, drec->sql_desc_type);		break;	case SQL_DESC_TYPE_NAME:		COUT(drec->sql_desc_type_name);		break;	case SQL_DESC_UNNAMED:		IOUT(SQLSMALLINT, drec->sql_desc_unnamed);		break;	case SQL_DESC_UNSIGNED:		IOUT(SQLSMALLINT, drec->sql_desc_unsigned);		break;	case SQL_DESC_UPDATABLE:		IOUT(SQLSMALLINT, drec->sql_desc_updatable);		break;	default:		tdsdump_log(TDS_DBG_INFO2, "odbc:SQLColAttribute: fDescType %d not catered for...\n", fDescType);		odbc_errs_add(&stmt->errs, "HY091", NULL);		ODBC_RETURN(stmt, SQL_ERROR);		break;	}	if (result == SQL_SUCCESS_WITH_INFO)		odbc_errs_add(&stmt->errs, "01004", NULL);	ODBC_RETURN(stmt, result);#undef COUT#undef SOUT#undef IOUT}SQLRETURN ODBC_APISQLColAttributes(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,		 SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc){	tdsdump_log(TDS_DBG_FUNC, "SQLColAttributes(%p, %d, %d, %p, %d, %p, %p)\n", 			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);}#if (ODBCVER >= 0x0300)SQLRETURN ODBC_APISQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,		SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc,#ifdef TDS_SQLCOLATTRIBUTE_SQLLEN		SQLLEN FAR * pfDesc#else		SQLPOINTER pfDesc#endif	){	tdsdump_log(TDS_DBG_FUNC, "SQLColAttribute(%p, %u, %u, %p, %d, %p, %p)\n", 			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);}#endifSQLRETURN ODBC_APISQLDisconnect(SQLHDBC hdbc){	int i;	INIT_HDBC;	tdsdump_log(TDS_DBG_FUNC, "SQLDisconnect(%p)\n", hdbc);	/* free all associated statements */	while (dbc->stmt_list)		_SQLFreeStmt(dbc->stmt_list, SQL_DROP, 1);	/* free all associated descriptors */	for (i = 0; i < TDS_MAX_APP_DESC; ++i) {		if (dbc->uad[i]) {			desc_free(dbc->uad[i]);			dbc->uad[i] = NULL;		}	}	tds_free_socket(dbc->tds_socket);	dbc->tds_socket = NULL;	dbc->cursor_support = 0;	ODBC_RETURN_(dbc);}static intodbc_errmsg_handler(const TDSCONTEXT * ctx, TDSSOCKET * tds, TDSMESSAGE * msg){	struct _sql_errors *errs = NULL;	TDS_DBC *dbc = NULL;	tdsdump_log(TDS_DBG_INFO1, "msgno %d %d\n", (int) msg->msgno, TDSETIME);	if (msg->msgno == TDSETIME) {		tdsdump_log(TDS_DBG_INFO1, "in timeout\n");		if (tds && (dbc = (TDS_DBC *) tds->parent) && dbc->current_statement) {			TDS_STMT *stmt = dbc->current_statement;			/* cancel sent, handling interrupt */			if (tds->in_cancel && stmt->cancel_sent) {				stmt->cancel_sent = 0;				tdsdump_log(TDS_DBG_INFO1, "returning from timeout\n");				return TDS_INT_TIMEOUT;			}			if (!tds->in_cancel)				odbc_errs_add(&stmt->errs, "HYT00", "Timeout expired");			stmt->errs.lastrc = SQL_ERROR;			/* attent indefinitely cancel */			/* stmt->dbc->tds_socket->query_timeout = 0; */		} else if (dbc) {			odbc_errs_add(&dbc->errs, "HYT00", "Timeout expired");			dbc->errs.lastrc = SQL_ERROR;			tds_close_socket(tds);			tdsdump_log(TDS_DBG_INFO1, "returning cancel from timeout\n");			return TDS_INT_CANCEL;		}		if (tds->in_cancel) {			tds_close_socket(tds);			tdsdump_log(TDS_DBG_INFO1, "returning cancel from timeout\n");			return TDS_INT_CANCEL;		}		tdsdump_log(TDS_DBG_INFO1, "returning from timeout\n");		return TDS_INT_TIMEOUT;	}	if (tds && tds->parent) {		dbc = (TDS_DBC *) tds->parent;		errs = &dbc->errs;		if (dbc->current_statement)			errs = &dbc->current_statement->errs;		/* set server info if not setted in dbc */		if (msg->server && tds_dstr_isempty(&dbc->server))			tds_dstr_copy(&dbc->server, msg->server);	} else if (ctx->parent) {		errs = &((TDS_ENV *) ctx->parent)->errs;	}	if (errs) {		int severity = msg->severity;		const char * state = msg->sql_state;		/* fix severity for Sybase */		if (severity <= 10 && dbc && !TDS_IS_MSSQL(dbc->tds_socket) && msg->sql_state && msg->sql_state[0]		    && strncmp(msg->sql_state, "00", 2) != 0) {			if (strncmp(msg->sql_state, "01", 2) != 0 && strncmp(msg->sql_state, "IM", 2) != 0)				severity = 11;		}		/* compute state if not available */		if (!state)			state = severity <= 10 ? "01000" : "42000";		/* add error, do not overwrite connection timeout error */		if (msg->msgno != TDSEFCON || errs->lastrc != SQL_ERROR || errs->num_errors < 1)			odbc_errs_add_rdbms(errs, msg->msgno, state, msg->message, msg->line_number, msg->severity,					    msg->server);		/* set lastc according */		if (severity <= 10) {			if (errs->lastrc == SQL_SUCCESS)				errs->lastrc = SQL_SUCCESS_WITH_INFO;		} else {			errs->lastrc = SQL_ERROR;		}	}	return TDS_INT_CANCEL;}/* TODO optimize, change only if some data change (set same value should not set this flag) */#define DESC_SET_NEED_REPREPARE \	do {\		if (desc->type == DESC_IPD) {\			assert(IS_HSTMT(desc->parent));\			((TDS_STMT *) desc->parent)->need_reprepare = 1;\		 }\	} while(0)SQLRETURN ODBC_APISQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLSMALLINT nSubType, SQLLEN nLength,	      SQLSMALLINT nPrecision, SQLSMALLINT nScale, SQLPOINTER pData, SQLLEN FAR * pnStringLength, SQLLEN FAR * pnIndicator){	struct _drecord *drec;	SQLSMALLINT concise_type;	INIT_HDESC;	tdsdump_log(TDS_DBG_FUNC, "SQLSetDescRec(%p, %d, %d, %d, %d, %d, %d, %p, %p, %p)\n", 			hdesc, nRecordNumber, nType, nSubType, (int)nLength, nPrecision, nScale, pData, pnStringLength, pnIndicator);	if (desc->type == DESC_IRD) {		odbc_errs_add(&desc->errs, "HY016", NULL);		ODBC_RETURN(desc, SQL_ERROR);	}	if (nRecordNumber > desc->header.sql_desc_count || nRecordNumber < 0) {		odbc_errs_add(&desc->errs, "07009", NULL);		ODBC_RETURN(desc, SQL_ERROR);	}	drec = &desc->records[nRecordNumber];	/* check for valid types and return "HY021" if not */	if (desc->type == DESC_IPD) {		DESC_SET_NEED_REPREPARE;		concise_type = odbc_get_concise_sql_type(nType, nSubType);	} else {		concise_type = odbc_get_concise_c_type(nType, nSubType);	}	if (nType == SQL_INTERVAL || nType == SQL_DATETIME) {		if (!concise_type) {			odbc_errs_add(&desc->errs, "HY021", NULL);			ODBC_RETURN(desc, SQL_ERROR);		}	} else {		if (concise_type != nType) {			odbc_errs_add(&desc->errs, "HY021", NULL);			ODBC_RETURN(desc, SQL_ERROR);		}		nSubType = 0;	}	drec->sql_desc_concise_type = concise_type;	drec->sql_desc_type = nType;	drec->sql_desc_datetime_interval_code = nSubType;	drec->sql_desc_octet_length = nLength;	drec->sql_desc_precision = nPrecision;	drec->sql_desc_scale = nScale;	drec->sql_desc_data_ptr = pData;	drec->sql_desc_octet_length_ptr = pnStringLength;	drec->sql_desc_indicator_ptr = pnIndicator;	ODBC_RETURN_(desc);}SQLRETURN ODBC_APISQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCH

⌨️ 快捷键说明

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