示例#1
0
int
main(int argc, char *argv[])
{
	int result;
	int retcode = 0;

	Connect();

	/* create table */
	CommandWithResult(Statement, "DROP TABLE TestTransaction");
	result = CommandWithResult(Statement, "CREATE TABLE TestTransaction ( value INT )");
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't create table TestTransaction");
		retcode = 1;
		goto cleanup;
	}

	if (!retcode)
		retcode = Test(1);
	if (!retcode)
		retcode = Test(0);

      cleanup:
	/* drop table */
	CommandWithResult(Statement, "DROP TABLE TestTransaction");

	Disconnect();

	printf("Done.\n");
	return retcode;
}
示例#2
0
static void
AutoCommit(int onoff)
{
	SQLRETURN ret;

	ret = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0);
	if (ret != SQL_SUCCESS)
		ODBC_REPORT_ERROR("Enabling AutoCommit");
}
示例#3
0
static void
EndTransaction(SQLSMALLINT type)
{
	SQLRETURN ret;

	ret = SQLEndTran(SQL_HANDLE_DBC, Connection, type);
	if (ret != SQL_SUCCESS)
		ODBC_REPORT_ERROR("Can't commit transaction");
}
示例#4
0
int
main(int argc, char *argv[])
{
	SQLLEN ind;
	int len = strlen(test_text), n, i;
	const char *p;
	char *pp;
	SQLPOINTER ptr;
	unsigned char buf[256], *pb;
	SQLRETURN RetCode;
	int type, lc, sql_type;

	odbc_connect();

	/* create table to hold data */
	odbc_command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");

	sql_type = SQL_LONGVARCHAR;
	type = SQL_C_CHAR;
	lc = 1;
	for (;;) {
		CHKBindParameter(1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind, "S");
		/* length required */
		ind = SQL_LEN_DATA_AT_EXEC(len * lc);

		/* 
		 * test for char 
		 */

		CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

		CHKExecute("Ne");

		p = test_text;
		n = 5;
		CHKParamData(&ptr, "Ne");
		if (ptr != (SQLPOINTER) 123)
			ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
		while (*p) {
			int l = strlen(p);

			if (l < n)
				n = l;
			if (type == SQL_C_CHAR) {
				CHKPutData((char *) p, n, "S");
			} else {
				SQLWCHAR buf[256];
				CHKPutData((char *) buf, to_sqlwchar(buf, p, n), "S");
			}
			p += n;
			n *= 2;
		}
		CHKParamData(&ptr, "S");

		CHKParamData(&ptr, "E");

		/* check state  and reset some possible buffers */
		odbc_command("DECLARE @i INT");

		/* use server ntext if available */
		if (sql_type == SQL_LONGVARCHAR && odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
			sql_type = SQL_WLONGVARCHAR;
			continue;
		}

		if (type != SQL_C_CHAR)
			break;
		sql_type = SQL_LONGVARCHAR;
		type = SQL_C_WCHAR;
		lc = sizeof(SQLWCHAR);
	}

	/* update row setting binary field */
	for (i = 0; i < 255; ++i)
		buf[i] = BYTE_AT(i);

	/* 
	 * test for binary 
	 */

	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind, "S");
	ind = SQL_LEN_DATA_AT_EXEC(254);

	CHKPrepare(T("UPDATE #putdata SET b = ?"), SQL_NTS, "S");

	CHKExecute("Ne");

	pb = buf;
	n = 7;
	CHKParamData(&ptr, "Ne");
	if (ptr != (SQLPOINTER) 4567)
		ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
	while (pb != (buf + 254)) {
		int l = buf + 254 - pb;

		if (l < n)
			n = l;
		CHKPutData((char *) pb, n, "S");
		pb += n;
		n *= 2;
	}
	CHKParamData(&ptr, "S");

	CHKParamData(&ptr, "E");

	/* check state  and reset some possible buffers */
	odbc_command("DECLARE @i2 INT");


	CHKFreeStmt(SQL_RESET_PARAMS, "S");

	/* check inserts ... there should be all equal rows */
	strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
	/* append binary */
	for (i = 0; i < 254; ++i)
		sprintf(strchr(sql, 0), "%02x", buf[i]);
	strcat(sql, " OR CONVERT(VARCHAR(255),c) <> '");
	/* append string */
	pp = strchr(sql, 0);
	p = test_text;
	do {
		*pp++ = *p;
		if (*p == '\'')
			*pp++ = *p;
	} while(*p++);
	strcat(sql, "') SELECT 1");
	odbc_check_no_row(sql);

	odbc_command("DELETE FROM #putdata");

	/* test len == 0 case from ML */
	type = SQL_C_CHAR;
	for (;;) {
		CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

		CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind, "S");

		ind = SQL_LEN_DATA_AT_EXEC(0);

		RetCode = CHKExecute("Ne");
		while (RetCode == SQL_NEED_DATA) {
			RetCode = SQLParamData(odbc_stmt, &ptr);
			if (RetCode == SQL_NEED_DATA) {
				if (type == SQL_C_CHAR) {
					CHKPutData("abc", 3, "S");
				} else {
					SQLWCHAR buf[10];
					CHKPutData(buf, to_sqlwchar(buf, "abc", 3), "S");
				}
			}
		}
		if (type != SQL_C_CHAR)
			break;
		type = SQL_C_WCHAR;
		odbc_reset_statement();
	}

	/* check inserts ... */
	odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE 'abc') SELECT 1");

	odbc_command("DELETE FROM #putdata");

	/* test putting 0 bytes from Sebastien Flaesch */
	if (odbc_db_is_microsoft()) {
		type = SQL_C_CHAR;
		for (;;) {
			CHKPrepare(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "S");

			CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 10, 0, (PTR) 2, 10, &ind, "S");

			ind = SQL_DATA_AT_EXEC;

			RetCode = CHKExecute("Ne");
			while (RetCode == SQL_NEED_DATA) {
				RetCode = SQLParamData(odbc_stmt, &ptr);
				if (RetCode == SQL_NEED_DATA)
					CHKPutData("", 0, "S");
			}
			if (type != SQL_C_CHAR)
				break;
			type = SQL_C_WCHAR;
			odbc_reset_statement();
		}

		/* check inserts ... */
		odbc_check_no_row("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE '') SELECT 1");
	}

	/* TODO test cancel inside SQLExecute */

	odbc_disconnect();

	printf("Done.\n");
	return 0;
}
示例#5
0
static void
Test(int level)
{
	SQLRETURN result;
	SQLSMALLINT InParam = level;
	SQLSMALLINT OutParam = 1;
	SQLLEN cbReturnCode = 0, cbInParam = 0, cbOutParam = 0;
	SQLLEN cbOutString = SQL_NTS;

	char sql[80];

	printf("ODBC %d nocount %s select %s level %d\n", odbc_use_version3 ? 3 : 2,
	       g_nocount ? "yes" : "no", g_second_select ? "yes" : "no", level);

	ReturnCode = INVALID_RETURN;
	memset(&OutString, 0, sizeof(OutString));

	/* test with SQLExecDirect */
	sprintf(sql, "RAISERROR('An error occurred.', %d, 1)", level);
	result = odbc_command_with_result(odbc_stmt, sql);

	TestResult(result, level, "SQLExecDirect");

	/* test with SQLPrepare/SQLExecute */
	if (!SQL_SUCCEEDED(SQLPrepare(odbc_stmt, T(SP_TEXT), strlen(SP_TEXT)))) {
		fprintf(stderr, "SQLPrepare failure!\n");
		exit(1);
	}

	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode);
	SQLBindParameter(odbc_stmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam);
	SQLBindParameter(odbc_stmt, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam, 0, &cbOutParam);
	strcpy(OutString, "Invalid!");
	SQLBindParameter(odbc_stmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
			 &cbOutString);

	CHKExecute("S");

	/* first select, check data are returned.
	 * SET statements before does not affect results
	 */
	CheckData("");
	CHKFetch("S");
	CheckData("Here is the first row");

	result = SQLFetch(odbc_stmt);
	if (odbc_use_version3) {
		SQLTCHAR SqlState[6];
		SQLINTEGER NativeError;
		SQLTCHAR MessageText[1000];
		SQLSMALLINT TextLength;
		SQLRETURN expected;
		SQLLEN rows;

		if (result != SQL_NO_DATA)
			ODBC_REPORT_ERROR("SQLFetch should return NO DATA");
		CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, SqlState, &NativeError, MessageText,
				       ODBC_VECTOR_SIZE(MessageText), &TextLength, "No");
		result = SQLMoreResults(odbc_stmt);
		expected = level > 10 ? SQL_ERROR : SQL_SUCCESS_WITH_INFO;
		if (result != expected)
			ODBC_REPORT_ERROR("SQLMoreResults returned unexpected result");
		if (!g_second_select && g_nocount) {
			if (ReturnCode == INVALID_RETURN) {
				result = SQLMoreResults(odbc_stmt);
			} else {
				CheckReturnCode(result, 0);
				ReturnCode = INVALID_RETURN;
				TestResult(result, level, "SQLMoreResults");
				ReturnCode = 0;
			}
		} else {
			TestResult(result, level, "SQLMoreResults");
		}

		/* a recordset with only warnings/errors do not contains rows */
		if (CHKRowCount(&rows, "SE") == SQL_SUCCESS && rows != -1)
			ODBC_REPORT_ERROR("SQLRowCount returned some rows");
	} else {
		/* in ODBC 2 errors/warnings are not handled as different recordset */
		TestResult(result, level, "SQLFetch");
	}

	if (odbc_driver_is_freetds())
		CheckData("");

	if (!g_second_select) {
		SQLLEN rows;

		if (CHKRowCount(&rows, "SE") == SQL_SUCCESS && rows != -1)
			ODBC_REPORT_ERROR("SQLRowCount returned some rows");
		CheckReturnCode(result, g_nocount ? 0 : INVALID_RETURN);

		result = SQLMoreResults(odbc_stmt);
#ifdef ENABLE_DEVELOPING
		if (result != SQL_NO_DATA)
			ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA");

		ODBC_CHECK_ROWS(-2);
#endif
		CheckReturnCode(result, 0);
		return;
	}

	if (!odbc_use_version3 || !g_nocount) {
		/* mssql 2008 return SUCCESS_WITH_INFO with previous error */
		CHKMoreResults("S");
		result = SQL_SUCCESS;
	}

	CheckReturnCode(result, INVALID_RETURN);

	CheckData("");
	if (g_nocount && odbc_use_version3 && g_second_select && level >= 10) {
		if (CHKFetch("SE") == SQL_ERROR) {
			SQLMoreResults(odbc_stmt);
			CHKFetch("S");
		}
	} else {
		CHKFetch("S");
	}
	CheckData("Here is the last row");

	CHKFetch("No");
	CheckData("");

	if (!odbc_use_version3 || g_nocount)
		CheckReturnCode(result, 0);
#ifdef ENABLE_DEVELOPING
	else
		CheckReturnCode(result, INVALID_RETURN);
#endif

	/* FIXME how to handle return in store procedure ??  */
	result = SQLMoreResults(odbc_stmt);
#ifdef ENABLE_DEVELOPING
	if (result != SQL_NO_DATA)
		ODBC_REPORT_ERROR("SQLMoreResults return other data");
#endif

	CheckReturnCode(result, 0);

	CheckData("");
	ODBC_FREE();
}
示例#6
0
int
main(int argc, char *argv[])
{
	HENV env;
	HDBC dbc;
	HSTMT stmt;
	SQLRETURN ret;
	SQLINTEGER i;

	Connect();

	/* here we can't use temporary table cause we use two connection */
	CommandWithResult(Statement, "drop table test_timeout");
	Command(Statement, "create table test_timeout(n numeric(18,0) primary key, t varchar(30))");
	AutoCommit(SQL_AUTOCOMMIT_OFF);

	Command(Statement, "insert into test_timeout(n, t) values(1, 'initial')");
	EndTransaction(SQL_COMMIT);

	Command(Statement, "update test_timeout set t = 'second' where n = 1");

	/* save this connection and do another */
	env = Environment;
	dbc = Connection;
	stmt = Statement;
	Environment = SQL_NULL_HENV;
	Connection = SQL_NULL_HDBC;
	Statement = SQL_NULL_HSTMT;

	Connect();

	AutoCommit(SQL_AUTOCOMMIT_OFF);
	ret = SQLSetStmtAttr(Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0);
	if (ret != SQL_SUCCESS)
		ODBC_REPORT_ERROR("Error setting timeout");

	i = 1;
	ret = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &i, 0, NULL);
	if (ret != SQL_SUCCESS)
		ODBC_REPORT_ERROR("SQLBindParameter failure");

	if (SQLPrepare(Statement, (SQLCHAR *) "update test_timeout set t = 'bad' where n = ?", SQL_NTS) != SQL_SUCCESS)
		ODBC_REPORT_ERROR("SQLPrepare failure");
	ret = SQLExecute(Statement);
	if (ret != SQL_ERROR)
		ODBC_REPORT_ERROR("SQLExecute success ??");
	EndTransaction(SQL_ROLLBACK);

	/* TODO should return error S1T00 Timeout expired, test error message */
	ret = CommandWithResult(Statement, "update test_timeout set t = 'bad' where n = 1");
	if (ret != SQL_ERROR)
		ODBC_REPORT_ERROR("SQLExecDirect success ??");

	EndTransaction(SQL_ROLLBACK);

	Disconnect();

	Environment = env;
	Connection = dbc;
	Statement = stmt;

	EndTransaction(SQL_COMMIT);

	/* Sybase do not accept DROP TABLE during a transaction */
	AutoCommit(SQL_AUTOCOMMIT_ON);
	Command(Statement, "drop table test_timeout");

	Disconnect();

	return 0;
}
示例#7
0
文件: array.c 项目: hanky6/freetds
static void
query_test(int prepare, SQLRETURN expected, const char *expected_status)
{
#define DESC_LEN 51
#define ARRAY_SIZE 10

    SQLUINTEGER *ids = XMALLOC_N(SQLUINTEGER,ARRAY_SIZE);
    typedef SQLCHAR desc_t[DESC_LEN];
    desc_t *descs = XMALLOC_N(desc_t, ARRAY_SIZE);
    SQLLEN *id_lens = XMALLOC_N(SQLLEN,ARRAY_SIZE), *desc_lens = XMALLOC_N(SQLLEN,ARRAY_SIZE);
    SQLUSMALLINT i, *statuses = XMALLOC_N(SQLUSMALLINT,ARRAY_SIZE);
    unsigned *num_errors = XMALLOC_N(unsigned, ARRAY_SIZE);
    SQLULEN processed;
    RETCODE ret;
    char status[20];
    SQLTCHAR *err = ODBC_GET(sizeof(odbc_err)*sizeof(SQLTCHAR));
    SQLTCHAR *state = ODBC_GET(sizeof(odbc_sqlstate)*sizeof(SQLTCHAR));

    assert(odbc_stmt != SQL_NULL_HSTMT);
    odbc_reset_statement();

    odbc_command_with_result(odbc_stmt, "drop table #tmp1");
    odbc_command("create table #tmp1 (id tinyint, value char(20))");

    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAMSET_SIZE, (void *) ARRAY_SIZE, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAM_STATUS_PTR, statuses, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &processed, 0);
    SQLBindParameter(odbc_stmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens);
    SQLBindParameter(odbc_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, DESC_LEN - 1, 0, descs, DESC_LEN, desc_lens);

    processed = ARRAY_SIZE + 1;
    for (i = 0; i < ARRAY_SIZE; i++) {
        statuses[i] = SQL_PARAM_DIAG_UNAVAILABLE;
        ids[i] = (i + 1) * multiply;
        sprintf((char *) descs[i], "data %d", i * 7);
        id_lens[i] = 0;
        desc_lens[i] = SQL_NTS;
        num_errors[i] = 0;
    }
    multiply = 90;

    if (!prepare) {
        ret = SQLExecDirect(odbc_stmt, test_query, SQL_NTS);
    } else {
        SQLPrepare(odbc_stmt, test_query, SQL_NTS);
        ret = SQLExecute(odbc_stmt);
    }

    if (processed > ARRAY_SIZE) {
        char buf[256];

        sprintf(buf, "Invalid processed number: %d", (int) processed);
        ODBC_REPORT_ERROR(buf);
    }

    for (i = 1; CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, i, state, NULL, err, sizeof(odbc_err), NULL, "SINo") != SQL_NO_DATA; ++i) {
        SQLINTEGER row;

        strcpy(odbc_err, C(err));
        strcpy(odbc_sqlstate, C(state));
        CHKGetDiagField(SQL_HANDLE_STMT, odbc_stmt, i, SQL_DIAG_ROW_NUMBER, &row, sizeof(row), NULL, "S");

        if (row == SQL_ROW_NUMBER_UNKNOWN) continue;
        if (row < 1 || row > ARRAY_SIZE) {
            fprintf(stderr, "invalid row %d returned reading error number %d\n", (int) row, i);
            exit(1);
        }
        ++num_errors[row-1];
        printf("for row %2d returned '%s' %s\n", (int) row, odbc_sqlstate, odbc_err);
    }

    for (i = 0; i < processed; ++i) {
        int has_diag = 0;

        switch (statuses[i]) {
        case SQL_PARAM_SUCCESS_WITH_INFO:
            has_diag = 1;
        case SQL_PARAM_SUCCESS:
            status[i] = 'V';
            break;

        case SQL_PARAM_ERROR:
            has_diag = 1;
            status[i] = '!';
            break;

        case SQL_PARAM_UNUSED:
            status[i] = ' ';
            break;

        case SQL_PARAM_DIAG_UNAVAILABLE:
            status[i] = '?';
            break;
        default:
            fprintf(stderr, "Invalid status returned %d\n", statuses[i]);
            exit(1);
        }

        if (has_diag) {
            if (!num_errors[i]) {
                fprintf(stderr, "Diagnostics not returned for status %d\n", i);
                failure = 1;
            }
        } else {
            if (num_errors[i]) {
                fprintf(stderr, "Diagnostics returned for status %d\n", i);
                failure = 1;
            }
        }
    }
    status[i] = 0;

    if (ret != expected || strcmp(expected_status, status) != 0) {
        fprintf(stderr, "Invalid result: got %d \"%s\" expected %d \"%s\" processed %d\n",
                ret, status, expected, expected_status, (int) processed);
        if (ret != SQL_SUCCESS)
            odbc_read_error();
        failure = 1;
        odbc_reset_statement();
        return;
    }

    odbc_reset_statement();
}
示例#8
0
文件: connect.c 项目: RQZeng/freetds
int
main(int argc, char *argv[])
{
	char tmp[2048];
	SQLSMALLINT len;
	int succeeded = 0;
	int is_freetds = 1;
	SQLRETURN rc;

	if (odbc_read_login_info())
		exit(1);

	/*
	 * prepare our odbcinst.ini 
	 * is better to do it before connect cause uniODBC cache INIs
	 * the name must be odbcinst.ini cause unixODBC accept only this name
	 */
	if (odbc_driver[0]) {
		FILE *f = fopen("odbcinst.ini", "w");

		if (f) {
			fprintf(f, "[FreeTDS]\nDriver = %s\n", odbc_driver);
			fclose(f);
			/* force iODBC */
			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
			setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
			/* force unixODBC (only directory) */
			setenv("ODBCSYSINI", ".", 1);
		}
	}

	printf("SQLConnect connect..\n");
	odbc_connect();
	if (!odbc_driver_is_freetds())
		is_freetds = 0;
	odbc_disconnect();
	++succeeded;

	if (!is_freetds) {
		printf("Driver is not FreeTDS, exiting\n");
		return 0;
	}

	/* try connect string with using DSN */
	printf("connect string DSN connect..\n");
	init_connect();
	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
	CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
	odbc_disconnect();
	++succeeded;

	/* try connect string using old SERVERNAME specification */
	printf("connect string SERVERNAME connect..\n");
	printf("odbcinst.ini must be configured with FreeTDS driver..\n");

	/* this is expected to work with unixODBC */
	init_connect();
	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
	rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
	if (rc == SQL_ERROR) {
		printf("Unable to open data source (ret=%d)\n", rc);
	} else {
		++succeeded;
	}
	odbc_disconnect();

	/* this is expected to work with iODBC */
	init_connect();
	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_driver, odbc_server, odbc_user, odbc_password, odbc_database);
	rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
	if (rc == SQL_ERROR) {
		printf("Unable to open data source (ret=%d)\n", rc);
	} else {
		++succeeded;
	}
	odbc_disconnect();

#ifdef _WIN32
	if (get_entry("SERVER")) {
		init_connect();
		sprintf(tmp, "DRIVER=FreeTDS;SERVER=%s;UID=%s;PWD=%s;DATABASE=%s;", entry, odbc_user, odbc_password, odbc_database);
		if (get_entry("TDS_Version"))
			sprintf(strchr(tmp, 0), "TDS_Version=%s;", entry);
		rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SIE");
		if (rc == SQL_ERROR) {
			printf("Unable to open data source (ret=%d)\n", rc);
		} else {
			++succeeded;
		}
		odbc_disconnect();
	}
#endif

	/* at least one should success.. */
	if (succeeded < 3) {
		ODBC_REPORT_ERROR("Too few successes");
		exit(1);
	}

	printf("Done.\n");
	return 0;
}
示例#9
0
static int
Test(int discard_test)
{
	SQLINTEGER out_buf;
	SQLLEN out_len;
	int result = 0;
	SQLLEN rows;
	int retcode = 0;
	char buf[512];
	unsigned char sqlstate[6];

	const char *createErrorProcedure = "CREATE PROCEDURE testerror AS\n"
		"SELECT value FROM TestTransaction\n" "SELECT value / (value-value) FROM TestTransaction\n";

	/* select after insert is required to test data discarding */
	char createProcedure[512];

	sprintf(createProcedure,
		"CREATE PROCEDURE testinsert @value INT AS\n"
		"INSERT INTO TestTransaction VALUES ( @value )\n%s", discard_test ? "SELECT * FROM TestTransaction\n" : "");

	/* create stored proc */
	CommandWithResult(Statement, "DROP PROCEDURE testinsert");

	result = CommandWithResult(Statement, createProcedure);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't create proc testinsert");
		retcode = 1;
		goto cleanup;
	}

	/* create stored proc that generates an error */
	CommandWithResult(Statement, "DROP PROCEDURE testerror");

	result = CommandWithResult(Statement, createErrorProcedure);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't create proc testerror");
		retcode = 1;
		goto cleanup;
	}

	/* Start transaction */
	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't start transaction");
		retcode = 1;
		goto cleanup;
	}

	/* Insert a value */
	Command(Statement, "EXEC testinsert 1");

	/* we should be able to read row count */
	if (SQLRowCount(Statement, &rows) != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't get row counts");
		retcode = 1;
		goto cleanup;
	}

	/* Commit transaction */
	result = SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't commit transaction");
		retcode = 1;
		goto cleanup;
	}

	SQLCloseCursor(Statement);

	/* Start transaction */
	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't start transaction");
		retcode = 1;
		goto cleanup;
	}

	/* Insert another value */
	Command(Statement, "EXEC testinsert 2");

	/* Roll back transaction */
	result = SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_ROLLBACK);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't roll back transaction");
		retcode = 1;
		goto cleanup;
	}

	/* TODO test row inserted */

	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0);
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("Can't stop transaction");
		retcode = 1;
		goto cleanup;
	}

	/* generate an error */
	result = CommandWithResult(Statement, "EXEC testerror");
	if (result != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("error: SQLExecDirect: testerror");
		retcode = 1;
		goto cleanup;
	}
	if (SQLBindCol(Statement, 1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len) != SQL_SUCCESS) {
		ODBC_REPORT_ERROR("error: SQLBindCol: testerror");
		retcode = 1;
		goto cleanup;
	}

	while ((result = SQLFetch(Statement)) == SQL_SUCCESS) {
		printf("\t%ld\n", (long int) out_buf);
		if (out_buf != 1) {
			printf("error: expected to select 1 got %ld\n", (long int) out_buf);
			retcode = 1;
			goto cleanup;
		}
	}

	if (result != SQL_NO_DATA) {
		ODBC_REPORT_ERROR("error: SQLFetch: testerror");
		goto cleanup;
	}

	result = SQLMoreResults(Statement);
	printf("SQLMoreResults returned %d\n", result);

	if (result != SQL_ERROR) {
		printf("SQLMoreResults should return error\n");
		retcode = 1;
		goto cleanup;
	}

	result = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *)buf, sizeof(buf), NULL);
	if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
		fprintf(stderr, "Error not set (line %d)\n", __LINE__);
		retcode = 1;
		goto cleanup;
	}
	printf("err=%s\n", buf);

	result = SQLMoreResults(Statement);
	printf("SQLMoreResults returned %d\n", result);
	if (result != SQL_NO_DATA) {
		printf("SQLMoreResults should return error");
		retcode = 1;
		goto cleanup;
	}

      cleanup:
	/* drop table */
	CommandWithResult(Statement, "DROP PROCEDURE testinsert");
	CommandWithResult(Statement, "DROP PROCEDURE testerror");

	return retcode;
}
示例#10
-1
文件: date.c 项目: dparnell/freetds
static void
DoTest(int n)
{
	int res;

	SQLCHAR output[256];

	SQLSMALLINT colType;
	SQLULEN colSize;
	SQLSMALLINT colScale, colNullable;
	SQLLEN dataSize;

	TIMESTAMP_STRUCT ts;

	if (CommandWithResult(Statement, "select convert(datetime, '2002-12-27 18:43:21')") != SQL_SUCCESS)
		ODBC_REPORT_ERROR("Unable to execute statement");

	res = SQLFetch(Statement);
	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO)
		ODBC_REPORT_ERROR("Unable to fetch row");

	if (SQLDescribeCol(Statement, 1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable) != SQL_SUCCESS)
		ODBC_REPORT_ERROR("Error getting data");

	if (n == 0) {
		memset(&ts, 0, sizeof(ts));
		if (SQLGetData(Statement, 1, SQL_C_TIMESTAMP, &ts, sizeof(ts), &dataSize) != SQL_SUCCESS) {
			printf("Unable to get data col %d\n", 1);
			CheckReturn();
			exit(1);
		}
		sprintf((char *) output, "%04d-%02d-%02d %02d:%02d:%02d.000", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
	} else {
		if (SQLGetData(Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize) != SQL_SUCCESS) {
			printf("Unable to get data col %d\n", 1);
			CheckReturn();
			exit(1);
		}
	}

	printf("Date returned: %s\n", output);
	if (strcmp((char *) output, "2002-12-27 18:43:21.000") != 0) {
		printf("Invalid returned date\n");
		exit(1);
	}

	res = SQLFetch(Statement);
	if (res != SQL_NO_DATA)
		ODBC_REPORT_ERROR("Unable to fetch row");

	res = SQLCloseCursor(Statement);
	if (!SQL_SUCCEEDED(res))
		ODBC_REPORT_ERROR("Unable to close cursor");
}