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

📄 genparams.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
#include "common.h"#include <assert.h>#include <time.h>/* Test various type from odbc and to odbc */static char software_version[] = "$Id: genparams.c,v 1.23 2008/01/08 09:33:32 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };#ifdef TDS_NO_DMstatic const int tds_no_dm = 1;#elsestatic const int tds_no_dm = 0;#endifstatic int precision = 18;static int exec_direct = 0;static int prepare_before = 0;static int use_cursors = 0;static voidTest(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *expected){	char sbuf[1024];	unsigned char out_buf[256];	SQLLEN out_len = 0;	SQL_NUMERIC_STRUCT *num;	int i;	ResetStatement();	/* build store procedure to test */	Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");	sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, '%s')", type, type, value_to_convert);	Command(Statement, sbuf);	memset(out_buf, 0, sizeof(out_buf));	if (use_cursors) {		ResetStatement();		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLSetStmtAttr error");		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLSetStmtAttr error");	}	/* bind parameter */	if (exec_direct) {		if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,			     sizeof(out_buf), &out_len) != SQL_SUCCESS)			ODBC_REPORT_ERROR("Unable to bind output parameter");		/* call store procedure */		if (SQLExecDirect(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)			ODBC_REPORT_ERROR("Unable to execute store statement");	} else {		if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLPrepare() failure!");		if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,			     sizeof(out_buf), &out_len) != SQL_SUCCESS)			ODBC_REPORT_ERROR("Unable to bind output parameter");		if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLPrepare() failure!");		if (SQLExecute(Statement) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLExecute() failure!");	}	/* test results */	sbuf[0] = 0;	switch (out_c_type) {	case SQL_C_NUMERIC:		num = (SQL_NUMERIC_STRUCT *) out_buf;		sprintf(sbuf, "%d %d %d ", num->precision, num->scale, num->sign);		i = SQL_MAX_NUMERIC_LEN;		for (; i > 0 && !num->val[--i];);		for (; i >= 0; --i)			sprintf(strchr(sbuf, 0), "%02X", num->val[i]);		break;	case SQL_C_BINARY:		assert(out_len >= 0);		for (i = 0; i < out_len; ++i)			sprintf(strchr(sbuf, 0), "%02X", (int) out_buf[i]);		break;	default:		/* not supported */		assert(0);		break;	}	if (strcmp(sbuf, expected) != 0) {		fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);		exit(1);	}	Command(Statement, "drop proc spTestProc");}static voidTestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, const char *param_type, const char *value_to_convert){	char sbuf[1024];	unsigned char out_buf[256];	SQLLEN out_len = 0;	const char *expected = value_to_convert;	size_t value_len = strlen(value_to_convert);	const char *p;	ResetStatement();	/* execute a select to get data as wire */	if ((p = strstr(value_to_convert, " -> ")) != NULL) {		value_len = p - value_to_convert;		expected = p + 4;	}	sprintf(sbuf, "SELECT CONVERT(%s, '%.*s')", type, (int) value_len, value_to_convert);	Command(Statement, sbuf);	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);	if (!SQL_SUCCEEDED(SQLFetch(Statement)))		ODBC_REPORT_ERROR("Expected row");	if (SQLFetch(Statement) != SQL_NO_DATA)		ODBC_REPORT_ERROR("Row not expected");	if (SQLMoreResults(Statement) != SQL_NO_DATA)		ODBC_REPORT_ERROR("Recordset not expected");	/* create a table with a column of that type */	ResetStatement();	sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type);	Command(Statement, sbuf);	if (use_cursors) {		ResetStatement();		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLSetStmtAttr error");		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLSetStmtAttr error");	}	/* insert data using prepared statements */	sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");	if (exec_direct) {		SQLRETURN rc;		out_len = 1;		if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=		    SQL_SUCCESS)			ODBC_REPORT_ERROR("Unable to bind input parameter");		rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)			ODBC_REPORT_ERROR("SQLExecDirect() failure!");	} else {		SQLRETURN rc;		if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLPrepare() failure!");		out_len = 1;		if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=		    SQL_SUCCESS)			ODBC_REPORT_ERROR("Unable to bind input parameter");		if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)			ODBC_REPORT_ERROR("SQLPrepare() failure!");		rc = SQLExecute(Statement);		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)			ODBC_REPORT_ERROR("SQLExecute() failure!");	}	/* check is row is present */	ResetStatement();	sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, '%s')", param_type, expected);	Command(Statement, sbuf);	if (SQLFetch(Statement) != SQL_SUCCESS)		ODBC_REPORT_ERROR("Expected row");	if (SQLFetch(Statement) != SQL_NO_DATA)		ODBC_REPORT_ERROR("Row not expected");	if (SQLMoreResults(Statement) != SQL_NO_DATA)		ODBC_REPORT_ERROR("Recordset not expected");	Command(Statement, "DROP TABLE #tmp_insert");}static int big_endian = 1;static char version[32];static voidAllTests(void){	struct tm *ltime;	char buf[80];	time_t curr_time;	SQLINTEGER y, m, d;	char date[128];	printf("use_cursors %d exec_direct %d prepare_before %d\n", use_cursors, exec_direct, prepare_before);	/* FIXME why should return 38 0 as precision and scale ?? correct ?? */	precision = 18;	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");	Test("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");	precision = 38;	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");	TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");	/* MS driver behavior for output parameters is different */	if (driver_is_freetds())		Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");	else		Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");	/* FIXME our driver ignore precision for date */	precision = 3;	Test("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");	Test("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,	     big_endian ? "0000949700FB9640" : "979400004096FB00");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");	/* test timestamp millisecond round off */	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.001 -> 2005-07-22 09:51:34.000");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.002 -> 2005-07-22 09:51:34.003");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.003 -> 2005-07-22 09:51:34.003");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.004 -> 2005-07-22 09:51:34.003");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.005 -> 2005-07-22 09:51:34.007");	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34.006 -> 2005-07-22 09:51:34.007");	/* FIXME on ms driver first SQLFetch return SUCCESS_WITH_INFO for truncation error */	TestInput(SQL_C_TYPE_DATE, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 13:02:03 -> 2005-07-22 00:00:00");	/* replace date information with current date */	time(&curr_time);	ltime = localtime(&curr_time);	y = ltime->tm_year + 1900;	m = ltime->tm_mon + 1;	d = ltime->tm_mday;	/* server concept of data can be different so try ask to server */	Command(Statement, "SELECT GETDATE()");	SQLBindCol(Statement, 1, SQL_C_CHAR, date, sizeof(date), NULL);	if (SQLFetch(Statement) == SQL_SUCCESS) {		int a, b, c;		if (sscanf(date, "%d-%d-%d", &a, &b, &c) == 3) {			y = a;			m = b;			d = c;		}	}	SQLFetch(Statement);	SQLMoreResults(Statement);	SQLFreeStmt(Statement, SQL_UNBIND);	sprintf(buf, "2003-07-22 13:02:03 -> %04d-%02d-%02d 13:02:03", (int) y, (int) m, (int) d);	TestInput(SQL_C_TYPE_TIME, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", buf);	TestInput(SQL_C_FLOAT,  "FLOAT", SQL_REAL, "FLOAT", "1234.25");	TestInput(SQL_C_DOUBLE, "REAL", SQL_REAL, "FLOAT", "-1234.25");	TestInput(SQL_C_FLOAT,  "REAL", SQL_REAL, "FLOAT", "1234.25");	TestInput(SQL_C_DOUBLE, "FLOAT", SQL_REAL, "FLOAT", "-1234.25");	TestInput(SQL_C_FLOAT,  "FLOAT", SQL_FLOAT, "FLOAT", "1234.25");	TestInput(SQL_C_DOUBLE, "REAL", SQL_FLOAT, "FLOAT", "-1234.25");	TestInput(SQL_C_FLOAT,  "FLOAT", SQL_DOUBLE, "FLOAT", "1234.25");	TestInput(SQL_C_DOUBLE, "REAL", SQL_DOUBLE, "FLOAT", "-1234.25");	TestInput(SQL_C_UTINYINT, "TINYINT", SQL_TINYINT, "TINYINT", "231");	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");	TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");	/* TODO some Sybase versions */	if (db_is_microsoft() && strncmp(version, "08.00.", 6) == 0) {		Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");	}}intmain(int argc, char *argv[]){	SQLSMALLINT version_len;	use_odbc_version3 = 1;	Connect();	memset(version, 0, sizeof(version));	SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);	if (((char *) &big_endian)[0] == 1)		big_endian = 0;	for (use_cursors = 0; use_cursors <= 1; ++use_cursors) {		if (use_cursors) {			if (!tds_no_dm || !driver_is_freetds())				ResetStatement();			CheckCursor();		}		exec_direct = 1;		AllTests();		exec_direct = 0;		prepare_before = 1;		AllTests();		prepare_before = 0;		AllTests();	}	Disconnect();	printf("Done successfully!\n");	return 0;}

⌨️ 快捷键说明

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