コード例 #1
0
ファイル: paramcore.c プロジェクト: DavidRueter/freetds
int
main(int argc, char *argv[])
{
	SQLLEN cb = SQL_NTS;

	odbc_use_version3 = 1;

	odbc_connect();

	odbc_command_with_result(odbc_stmt, "drop proc sp_paramcore_test");
	odbc_command("create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");

	/* here we pass a NULL buffer for input SQL_NTS */
	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb, "S");

	cb = SQL_NTS;
	CHKExecDirect(T(SP_TEXT), SQL_NTS, "E");
	odbc_reset_statement();

	/* here we pass a NULL buffer for input */
	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb, "S");

	cb = 1;
	CHKExecDirect(T(SP_TEXT), SQL_NTS, "E");
	odbc_reset_statement();

	odbc_command("drop proc sp_paramcore_test");
	odbc_command("create proc sp_paramcore_test @s numeric(10,2) output as select @s = 12345.6");
	odbc_reset_statement();

#if 0	/* this fails even on native platforms */
	/* here we pass a NULL buffer for output */
	cb = sizeof(SQL_NUMERIC_STRUCT);
	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_OUTPUT, SQL_C_NUMERIC, SQL_NUMERIC, 18, 0, NULL, OUTSTRING_LEN, &cb);
	odbc_read_error();

	cb = 1;
	odbc_command_with_result(odbc_stmt, SP_TEXT);
	odbc_read_error();
	odbc_reset_statement();
#endif

	odbc_command("drop proc sp_paramcore_test");

	odbc_disconnect();

	printf("Done successfully!\n");
	return 0;
}
コード例 #2
0
ファイル: long_error.c プロジェクト: FreeTDS/freetds
int
main(void)
{
	int i;
	char cmd[128 + 110*10];

	printf("SQLWCHAR size is: %d\n", (int) sizeof(SQLWCHAR));

	odbc_use_version3 = 1;
	odbc_connect();

	/* this test do not work with Sybase */
	if (!odbc_db_is_microsoft()) {
		odbc_disconnect();
		return 0;
	}

	strcpy(cmd, "create procedure #proc_longerror as\nbegin\nraiserror('");
	for (i = 0; i < 110; ++i)
		strcat(cmd, "reallylong");
	strcat(cmd, " error', 16, 1)\nend\n");
	odbc_command(cmd);

	CHKExecDirect(T("{CALL #proc_longerror}"), SQL_NTS, "E");

	extract_error(odbc_stmt, SQL_HANDLE_STMT);

	odbc_disconnect();
	return 0;
}
コード例 #3
0
ファイル: prepclose.c プロジェクト: RQZeng/freetds
static int
Test(int direct)
{
	SQLTCHAR buf[256];
	SQLTCHAR sqlstate[6];

	odbc_connect();

	if (!close_last_socket()) {
		fprintf(stderr, "Error closing connection\n");
		return 1;
	}

	/* force disconnection closing socket */
	if (direct) {
		CHKExecDirect(T("SELECT 1"), SQL_NTS, "E");
	} else {
		SQLSMALLINT cols;
		/* use prepare, force dialog with server */
		if (CHKPrepare(T("SELECT 1"), SQL_NTS, "SE") == SQL_SUCCESS)
			CHKNumResultCols(&cols, "E");
	}

	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, buf, ODBC_VECTOR_SIZE(buf), NULL, "SI");
	sqlstate[5] = 0;
	printf("state=%s err=%s\n", C(sqlstate), C(buf));
	
	odbc_disconnect();

	printf("Done.\n");
	return 0;
}
コード例 #4
0
ファイル: binary_test.c プロジェクト: rzsis/freetds
static int
test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
{
    SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
    SQLLEN strlen_or_ind = 0;
    const char *qstr = "select * from " TEST_TABLE_NAME;

    assert(odbc_conn);
    assert(odbc_env);

    /* allocate new statement handle */
    CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");

    /* execute query */
    CHKExecDirect(T(qstr), SQL_NTS, "SINo");

    /* fetch first page of first result row of unbound column */
    CHKFetch("S");

    strlen_or_ind = 0;
    CHKGetData(1, SQL_C_BINARY, buf, buflen, &strlen_or_ind, "SINo");

    *bytes_returned = ((strlen_or_ind > buflen || (strlen_or_ind == SQL_NO_TOTAL)) ? buflen : strlen_or_ind);

    /* ensure that this was the only row */
    CHKFetch("No");

    SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
    ODBC_FREE();
    return 0;
}
コード例 #5
0
ファイル: cursor4.c プロジェクト: DmitrySigaev/ncbi
int
main(int argc, char **argv)
{
	char buff[64];
	SQLLEN ind;

	odbc_use_version3 = 1;
	odbc_connect();

	odbc_check_cursor();

	exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
	exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')");

	odbc_reset_statement();

	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S");

	CHKSetCursorName(T("c112"), SQL_NTS, "S");

	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_OFF), 0, "S");

	CHKPrepare(T("SELECT * FROM #t1 FOR UPDATE"), SQL_NTS, "S");

	CHKExecute("S");

	CHKFetch("S");

	exec_direct("UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");

	CHKCloseCursor("SI");

	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S");

	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_ON), 0, "S");

	CHKExecDirect(T("SELECT c FROM #t1 WHERE k = 1"), SQL_NTS, "S");

	CHKFetch("S");

	CHKGetData(1, SQL_C_CHAR, buff, sizeof(buff), &ind, "S");

	printf(">> New value after update = [%s] (should be [xxx]) \n", buff);

	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
	odbc_stmt = SQL_NULL_HSTMT;

	odbc_disconnect();

	return 0;
}
コード例 #6
0
ファイル: timeout4.c プロジェクト: DavidRueter/freetds
static int
Test(int direct)
{
	SQLTCHAR buf[256];
	SQLTCHAR sqlstate[6];
	time_t start_time, end_time;

	odbc_mark_sockets_opened();
	odbc_connect();

	if (!shutdown_last_socket()) {
		fprintf(stderr, "Error shutting down connection\n");
		return 1;
	}

	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "S");

	alarm(30);
	start_time = time(NULL);
	if (direct) {
		CHKExecDirect(T("SELECT 1"), SQL_NTS, "E");
	} else {
		SQLSMALLINT cols;
		/* force dialog with server */
		if (CHKPrepare(T("SELECT 1"), SQL_NTS, "SE") == SQL_SUCCESS)
			CHKNumResultCols(&cols, "E");
	}
	end_time = time(NULL);
	alarm(0);

	memset(sqlstate, 'X', sizeof(sqlstate));
	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, buf, ODBC_VECTOR_SIZE(buf), NULL, "SI");
	sqlstate[5] = 0;
	printf("Message: %s - %s\n", C(sqlstate), C(buf));
	if (strcmp(C(sqlstate), "HYT00") || !strstr(C(buf), "Timeout")) {
		fprintf(stderr, "Invalid timeout message\n");
		return 1;
	}
	if (end_time - start_time < 10 || end_time - start_time > 26) {
		fprintf(stderr, "Unexpected connect timeout (%d)\n", (int) (end_time - start_time));
		return 1;
	}

	odbc_disconnect();

	if (end_socket >= 0)
		close(end_socket);

	printf("Done.\n");
	return 0;
}
コード例 #7
0
ファイル: genparams.c プロジェクト: rzsis/freetds
/* stripped down version of TestInput for NULLs */
static void
NullInput(SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *param_type)
{
    char sbuf[1024];
    SQLLEN out_len = SQL_NULL_DATA;

    odbc_reset_statement();

    /* create a table with a column of that type */
    odbc_reset_statement();
    sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s NULL)", param_type);
    odbc_command(sbuf);

    if (use_cursors) {
        odbc_reset_statement();
        CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
        CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
    }

    /* insert data using prepared statements */
    sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");
    if (exec_direct) {
        CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S");

        CHKExecDirect(T(sbuf), SQL_NTS, "SNo");
    } else {
        if (prepare_before)
            CHKPrepare(T(sbuf), SQL_NTS, "S");

        CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S");

        if (!prepare_before)
            CHKPrepare(T(sbuf), SQL_NTS, "S");

        CHKExecute("SNo");
    }

    /* check if row is present */
    odbc_reset_statement();
    if (!odbc_db_is_microsoft() && strcmp(param_type, "TEXT") == 0)
        odbc_command("SELECT * FROM #tmp_insert WHERE col LIKE ''");
    else
        odbc_command("SELECT * FROM #tmp_insert WHERE col IS NULL");

    CHKFetch("S");
    CHKFetch("No");
    CHKMoreResults("No");
    odbc_command("DROP TABLE #tmp_insert");
    ODBC_FREE();
}
コード例 #8
0
ファイル: cancel.c プロジェクト: angcoch/freetds
static void
Test(int use_threads, int return_data)
{
	tds_thread wait_thread;

#if !HAVE_ALARM
	if (!use_threads) return;
#endif

	printf("testing with %s\n", use_threads ? "threads" : "signals");
	printf(">> Wait 5 minutes...\n");
	if (!use_threads) {
		alarm(4);
		signal(SIGALRM, sigalrm_handler);
	} else {
		int err;

		exit_thread = 0;
		err = tds_thread_create(&wait_thread, wait_thread_proc, NULL);
		if (err != 0) {
			perror("tds_thread_create");
			exit(1);
		}
	}
	if (!return_data)
		CHKExecDirect(T("WAITFOR DELAY '000:05:00'"), SQL_NTS, "E");
	else
		odbc_command2("SELECT MAX(p1.k) FROM tab1 p1, tab1 p2, tab1 p3, tab1 p4", "E");

	tds_mutex_lock(&mtx);
	exit_thread = 1;
	tds_mutex_unlock(&mtx);
	if (!use_threads) {
		alarm(0);
	} else {
		tds_thread_join(wait_thread, NULL);
	}
	getErrorInfo(SQL_HANDLE_STMT, odbc_stmt);
	if (strcmp(C(sqlstate), "HY008") != 0) {
		fprintf(stderr, "Unexpected sql state returned\n");
		odbc_disconnect();
		exit(1);
	}

	odbc_reset_statement();

	odbc_command("SELECT name FROM sysobjects WHERE 0=1");
}
コード例 #9
0
ファイル: common.c プロジェクト: angcoch/freetds
int
odbc_connect(void)
{
	ODBC_BUF *odbc_buf = NULL;
	char command[512];
	const char *p;

	if (odbc_read_login_info())
		exit(1);

	if (odbc_use_version3) {
		CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
		SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
		CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
	} else {
		CHKAllocEnv(&odbc_env, "S");
		CHKAllocConnect(&odbc_conn, "S");
	}

	printf("odbctest\n--------\n\n");
	printf("connection parameters:\nserver:   '%s'\nuser:     '******'\npassword: '******'\ndatabase: '%s'\n",
	       odbc_server, odbc_user, "????" /* odbc_password */ , odbc_database);

	p = getenv("ODBC_MARS");
	if (p && atoi(p) != 0)
		SQLSetConnectAttr(odbc_conn, 1224 /*SQL_COPT_SS_MARS_ENABLED*/, (SQLPOINTER) 1 /*SQL_MARS_ENABLED_YES*/, SQL_IS_UINTEGER);
	if (odbc_set_conn_attr)
		(*odbc_set_conn_attr)();

	CHKConnect(T(odbc_server), SQL_NTS, T(odbc_user), SQL_NTS, T(odbc_password), SQL_NTS, "SI");

	CHKAllocStmt(&odbc_stmt, "S");

	sprintf(command, "use %s", odbc_database);
	printf("%s\n", command);

	CHKExecDirect(T(command), SQL_NTS, "SI");

#ifndef TDS_NO_DM
	/* unixODBC seems to require it */
	SQLMoreResults(odbc_stmt);
#endif
	ODBC_FREE();
	return 0;
}
コード例 #10
0
ファイル: utf8.c プロジェクト: RQZeng/freetds
static void
CheckNoRow(const char *query)
{
	SQLRETURN rc;

	rc = CHKExecDirect(T(query), SQL_NTS, "SINo");
	if (rc == SQL_NO_DATA)
		return;

	do {
		SQLSMALLINT cols;

		CHKNumResultCols(&cols, "S");
		if (cols != 0) {
			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
			exit(1);
		}
	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
}
コード例 #11
0
ファイル: common.c プロジェクト: hankinsoft/freetds_framework
int
odbc_connect(void)
{
    char command[512];

    if (odbc_read_login_info())
        exit(1);

    if (odbc_use_version3) {
        CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
        SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
        CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
    } else {
        CHKAllocEnv(&odbc_env, "S");
        CHKAllocConnect(&odbc_conn, "S");
    }

    printf("odbctest\n--------\n\n");
    printf("connection parameters:\nserver:   '%s'\nuser:     '******'\npassword: '******'\ndatabase: '%s'\n",
           odbc_server, odbc_user, "????" /* odbc_password */ , odbc_database);

    if (odbc_set_conn_attr)
        (*odbc_set_conn_attr)();

    CHKR(SQLConnect, (odbc_conn, (SQLCHAR *) odbc_server, SQL_NTS, (SQLCHAR *) odbc_user, SQL_NTS, (SQLCHAR *) odbc_password, SQL_NTS), "SI");

    CHKAllocStmt(&odbc_stmt, "S");

    sprintf(command, "use %s", odbc_database);
    printf("%s\n", command);

    CHKExecDirect((SQLCHAR *) command, SQL_NTS, "SI");

#ifndef TDS_NO_DM
    /* unixODBC seems to require it */
    SQLMoreResults(odbc_stmt);
#endif
    return 0;
}
コード例 #12
0
ファイル: putdata.c プロジェクト: FreeTDS/freetds
static void
Test(int direct)
{
	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;

	/* create table to hold data */
	odbc_command_with_result(odbc_stmt, "DROP TABLE #putdata");
	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 
		 */

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

			CHKExecute("Ne");
		} else {
			CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
		}

		p = test_text;
		n = 5;
		ptr = ((char*)0) + 0xdeadbeef;
		CHKParamData(&ptr, "Ne");
		if (ptr != (SQLPOINTER) 123) {
			fprintf(stderr, "%p\n", ptr);
			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 (;;) {
		if (!direct)
			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);

		if (!direct)
			CHKExecute("Ne");
		else
			CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
		RetCode = SQL_NEED_DATA;
		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 (;;) {
			if (!direct)
				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;

			if (!direct)
				CHKExecute("Ne");
			else
				CHKExecDirect(T("INSERT INTO #putdata(c) VALUES(?)"), SQL_NTS, "Ne");
			RetCode = SQL_NEED_DATA;
			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 */
}
コード例 #13
0
ファイル: genparams.c プロジェクト: rzsis/freetds
static int
TestOutput(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;
    const char *sep;

    odbc_reset_statement();

    /* build store procedure to test */
    odbc_command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
    sep = "'";
    if (strncmp(value_to_convert, "0x", 2) == 0)
        sep = "";
    sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep);
    odbc_command(sbuf);
    memset(out_buf, 0, sizeof(out_buf));

    if (use_cursors) {
        odbc_reset_statement();
        CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
        CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
    }

    /* bind parameter */
    if (exec_direct) {
        CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
                         sizeof(out_buf), &out_len, "S");

        /* call store procedure */
        CHKExecDirect(T("{call spTestProc(?)}"), SQL_NTS, "S");
    } else {
        if (prepare_before)
            CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S");

        CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
                         sizeof(out_buf), &out_len, "S");

        if (!prepare_before)
            CHKPrepare(T("{call spTestProc(?)}"), SQL_NTS, "S");

        CHKExecute("S");
    }

    /*
     * MS OBDC requires it cause first recordset is a recordset with a
     * warning caused by the way it execute RPC (via EXEC statement)
     */
    if (use_cursors && !odbc_driver_is_freetds())
        SQLMoreResults(odbc_stmt);

    /* test results */
    odbc_c2string(sbuf, out_c_type, out_buf, out_len);

    if (strcmp(sbuf, expected) != 0) {
        if (only_test) {
            odbc_command("drop proc spTestProc");
            ODBC_FREE();
            return 1;
        }
        fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);
        exit(1);
    }
    only_test = 0;
    odbc_command("drop proc spTestProc");
    ODBC_FREE();
    return 0;
}
コード例 #14
0
ファイル: genparams.c プロジェクト: rzsis/freetds
static void
TestInput(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;
    const char *sep = "'";

    odbc_reset_statement();

    /* execute a select to get data as wire */
    if ((p = strstr(value_to_convert, " -> ")) != NULL) {
        value_len = p - value_to_convert;
        expected = p + 4;
    }
    if (value_len >= 2 && strncmp(value_to_convert, "0x", 2) == 0)
        sep = "";
    sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep);
    odbc_command(sbuf);
    SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
    CHKFetch("SI");
    CHKFetch("No");
    CHKMoreResults("No");
    if (use_nts) {
        out_len = SQL_NTS;
        use_nts = 0;
    }

    /* create a table with a column of that type */
    odbc_reset_statement();
    sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type);
    odbc_command(sbuf);

    if (use_cursors) {
        odbc_reset_statement();
        CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
        CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
    }

    /* insert data using prepared statements */
    sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");
    if (exec_direct) {
        CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S");

        if (check_truncation)
            CHKExecDirect(T(sbuf), SQL_NTS, "E");
        else
            CHKExecDirect(T(sbuf), SQL_NTS, "SNo");
    } else {
        if (prepare_before)
            CHKPrepare(T(sbuf), SQL_NTS, "S");

        CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S");

        if (!prepare_before)
            CHKPrepare(T(sbuf), SQL_NTS, "S");

        if (check_truncation)
            CHKExecute("E");
        else
            CHKExecute("SNo");
    }

    /* check if row is present */
    if (!check_truncation) {
        odbc_reset_statement();
        sep = "'";
        if (strncmp(expected, "0x", 2) == 0)
            sep = "";
        if (strcmp(param_type, "TEXT") == 0)
            sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARCHAR(255), col) = CONVERT(VARCHAR(255), %s%s%s)", sep, expected, sep);
        else if (strcmp(param_type, "NTEXT") == 0)
            sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(NVARCHAR(2000), col) = CONVERT(NVARCHAR(2000), %s%s%s)", sep, expected, sep);
        else if (strcmp(param_type, "IMAGE") == 0)
            sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARBINARY(255), col) = CONVERT(VARBINARY(255), %s%s%s)", sep, expected, sep);
        else
            sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
        odbc_command(sbuf);

        CHKFetch("S");
        CHKFetch("No");
        CHKMoreResults("No");
    }
    check_truncation = 0;
    odbc_command("DROP TABLE #tmp_insert");
    ODBC_FREE();
}
コード例 #15
0
ファイル: array_out.c プロジェクト: hanky6/freetds
static void
query_test(const char* expected, const char *expected_status)
{
#define ARRAY_SIZE 10

    ODBC_BUF *odbc_buf = NULL;
    SQLUINTEGER *ids;
    SQLCHAR *descs;
    SQLLEN *id_lens, *desc_lens;
    SQLULEN processed;
    SQLUSMALLINT i, statuses[ARRAY_SIZE];
    int desc_len = trunc ? 4 : 51;
    int rec_size = 0;
    Record *rec = NULL;
    char status[20];

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

    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_STATUS_PTR, statuses, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_ARRAY_SIZE, (void *) ARRAY_SIZE, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROWS_FETCHED_PTR, &processed, 0);
    SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);

    if (!record_bind) {
        ids = (SQLUINTEGER *) ODBC_GET(sizeof(SQLUINTEGER) * ARRAY_SIZE);
        descs = ODBC_GET(sizeof(SQLCHAR) * ARRAY_SIZE * desc_len);
        desc_lens = (SQLLEN *) ODBC_GET(sizeof(SQLLEN) * ARRAY_SIZE);
        id_lens = (SQLLEN *) ODBC_GET(sizeof(SQLLEN) * ARRAY_SIZE);
        assert(descs && ids && desc_lens && id_lens);
    } else {
        rec_size = (sizeof(Record) + (sizeof(SQLCHAR) * desc_len + sizeof(SQLLEN) - 1)) & ~(sizeof(SQLLEN) - 1);
        SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_BIND_TYPE, int2ptr(rec_size), 0);
        rec = (Record *) ODBC_GET(rec_size * ARRAY_SIZE);
        ids = &rec->id;
        id_lens = &rec->id_len;
        desc_lens = &rec->desc_len;
        descs = (SQLCHAR *) (((char *) rec) + sizeof(Record));
    }
#define REC(f,n) (((char*)f)+rec_size*(n))
#define DESCS(n) (rec ? (SQLCHAR*)REC(descs,n): (descs+(n)*desc_len))
#define IDS(n) *(rec ? (SQLUINTEGER*)REC(ids,n) : &ids[n])
#define ID_LENS(n) *(rec ? (SQLLEN*)REC(id_lens,n) : &id_lens[n])
#define DESC_LENS(n) *(rec ? (SQLLEN*)REC(desc_lens,n) : &desc_lens[n])

    processed = ARRAY_SIZE + 1;
    for (i = 0; i < ARRAY_SIZE; i++) {
        statuses[i] = SQL_ROW_UPDATED;
        IDS(i) = i * 132;
        sprintf((char *) DESCS(i), "aaa");
        ID_LENS(i) = 0;
        DESC_LENS(i) = -i;
    }

    SQLBindCol(odbc_stmt, 1, SQL_C_ULONG, &IDS(0), 0, &ID_LENS(0));
    SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, DESCS(0), desc_len, &DESC_LENS(0));

    CHKExecDirect(T(test_query), SQL_NTS, "S");

    CHKFetch(expected);

    assert(processed <= ARRAY_SIZE);

    for (i = 0; i < processed; ++i) {
        char buf[128];

        sprintf(buf, "%crow number %d", 'a' + i, i * 13);
        if (trunc)
            buf[3] = 0;
        if (IDS(i) != i + 1 || strcmp((char *) DESCS(i), buf) != 0) {
            fprintf(stderr, "Invalid result\n\tgot '%d|%s'\n\texpected '%d|%s'\n", (int) IDS(i), DESCS(i), i + 1, buf);
            exit(1);
        }

        switch (statuses[i]) {
        case SQL_ROW_SUCCESS:
            status[i] = 'V';
            break;

        case SQL_ROW_SUCCESS_WITH_INFO:
            status[i] = 'v';
            break;

        case SQL_ROW_ERROR:
            status[i] = '!';
            break;

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

        default:
            fprintf(stderr, "Invalid status returned\n");
            exit(1);
        }
    }
    status[i] = 0;

    if (expected_status && strcmp(expected_status, status) != 0) {
        fprintf(stderr, "Invalid status\n\tgot '%s'\n\texpected '%s'\n", status, expected_status);
        exit(1);
    }

    ODBC_FREE();
}
コード例 #16
0
ファイル: common.c プロジェクト: rzsis/freetds
/* Detect protocol version using queries
 * This to make possible protocol discovery on drivers like MS
 */
static int
odbc_tds_version_long(void)
{
	SQLRETURN ret;
	SQLSMALLINT scale, nullable, type;
	SQLULEN prec;
	ODBC_BUF *odbc_buf = NULL;

	/* statement must be in a consistent state to do the check */
	CHKExecDirect(T("select 1"), SQL_NTS, "S");
	odbc_reset_statement();

	/* select cast(123 as sql_variant) -> nvarchar('123') is 7.0 failure query is 5.0 ?? */
	ret = CHKExecDirect(T("select cast('123' as sql_variant)"), SQL_NTS, "SNoE");
	odbc_reset_statement();
	if (ret == SQL_ERROR) {
		ODBC_FREE();
		return 0x500;
	}

	/* see how bigint is returned, numeric means 7.0 */
	CHKExecDirect(T("select cast('123' as bigint)"), SQL_NTS, "S");
	CHKDescribeCol(1, NULL, 0, NULL, &type, &prec, &scale, &nullable, "S");
	odbc_reset_statement();
	if (type == SQL_NUMERIC || type == SQL_DECIMAL) {
		ODBC_FREE();
		return 0x700;
	}
	if (type != SQL_BIGINT) {
		fprintf(stderr, "Strange type returned trying to detect protocol version\n");
		odbc_disconnect();
		ODBC_FREE();
		exit(1);
	}

	/* select cast('123' as varchar(max)) -> ??? SQL_VARCHAR is 7.2 ?? */
	ret = CHKExecDirect(T("select cast('123' as varchar(max))"), SQL_NTS, "SE");
	if (ret == SQL_ERROR) {
		odbc_reset_statement();
		ODBC_FREE();
		return 0x701;
	}
	CHKDescribeCol(1, NULL, 0, NULL, &type, &prec, &scale, &nullable, "S");
	odbc_reset_statement();
	if (type == SQL_LONGVARCHAR) {
		ODBC_FREE();
		return 0x701;
	}
	if (type != SQL_VARCHAR) {
		fprintf(stderr, "Strange type returned trying to detect protocol version\n");
		odbc_disconnect();
		ODBC_FREE();
		exit(1);
	}

	/* select cast('12:13:14.1234' as time(4)) -> NVARCHAR('12:13:14.1234') is 7.2 else 7.3 */
	ret = CHKExecDirect(T("select cast('12:13:14.1234' as time(4))"), SQL_NTS, "SE");
	if (ret == SQL_ERROR) {
		odbc_reset_statement();
		ODBC_FREE();
		return 0x702;
	}
	CHKDescribeCol(1, NULL, 0, NULL, &type, &prec, &scale, &nullable, "S");
	odbc_reset_statement();
	if (scale == 4)
		return 0x703;
	if (scale != 0 || type != SQL_WVARCHAR) {
		fprintf(stderr, "Strange type or scale returned trying to detect protocol version\n");
		odbc_disconnect();
		ODBC_FREE();
		exit(1);
	}

	ODBC_FREE();
	return 0x702;
}
コード例 #17
0
ファイル: cursor1.c プロジェクト: smalinin/FreeTDS
static void
Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *select_sql)
{
#define ROWS 4
#define C_LEN 10

	SQLUINTEGER n[ROWS];
	char c[ROWS][C_LEN];
	SQLLEN c_len[ROWS], n_len[ROWS];

	SQLUSMALLINT statuses[ROWS];
	SQLUSMALLINT i;
	SQLULEN num_row;
	SQLHSTMT stmt2;

	/* create test table */
	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
	odbc_command(create_sql);
	for (i = 1; i <= 6; ++i) {
		char sql_buf[80], data[10];
		memset(data, 'a' + (i - 1), sizeof(data));
		data[i] = 0;
		sprintf(sql_buf, insert_sql, data, i);
		odbc_command(sql_buf);
	}

	/* set cursor options */
	odbc_reset_statement();
	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
	CHKSetCursorName(T("C1"), SQL_NTS, "S");

	/* */
	CHKExecDirect(T(select_sql), SQL_NTS, "S");

	/* bind some rows at a time */
	CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S");
	CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S");

	/* allocate an additional statement */
	CHKAllocStmt(&stmt2, "S");

	while (CHKFetchScroll(SQL_FETCH_NEXT, 0, "SNo") == SQL_SUCCESS) {
		/* print, just for debug */
		for (i = 0; i < num_row; ++i)
			printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]);
		printf("---\n");

		/* delete a row */
		i = 1;
		if (i > 0 && i <= num_row) {
			if (mssql2005)
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "SI");
			else
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "S");
			if (use_sql) {
				SWAP_STMT(stmt2);
				CHKPrepare(T("DELETE FROM #test WHERE CURRENT OF C1"), SQL_NTS, "S");
				CHKExecute("S");
				SWAP_STMT(stmt2);
			}
		}

		/* update another row */
		i = 2;
		if (i > 0 && i <= num_row) {
			strcpy(c[i - 1], "foo");
			c_len[i - 1] = 3;
			if (strstr(select_sql, "#a") == NULL || use_sql) {
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "S");
			} else {
				SQLTCHAR sqlstate[6];
				SQLTCHAR msg[256];

				n[i - 1] = 321;
				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "E");

				CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, msg, ODBC_VECTOR_SIZE(msg), NULL, "S");
				if (strstr(C(msg), "Invalid column name 'c'") == NULL) {
					fprintf(stderr, "Expected message not found at line %d\n", __LINE__);
					exit(1);
				}
			}
			if (use_sql) {
				SWAP_STMT(stmt2);
				CHKPrepare(T("UPDATE #test SET c=? WHERE CURRENT OF C1"), SQL_NTS, "S");
				CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL, "S");
				CHKExecute("S");
				/* FIXME this is not necessary for mssql driver */
				SQLMoreResults(odbc_stmt);
				SWAP_STMT(stmt2);
			}
		}
	}

	SWAP_STMT(stmt2);
	CHKFreeStmt(SQL_DROP, "S");
	SWAP_STMT(stmt2);

	odbc_reset_statement();

	/* test values */
	CheckNoRow("IF (SELECT COUNT(*) FROM #test) <> 4 SELECT 1");
	CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 3 AND c = 'ccc') SELECT 1");
	CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 4 AND c = 'dddd') SELECT 1");
	if (strstr(select_sql, "#a") == NULL || use_sql) {
		CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 2 AND c = 'foo') SELECT 1");
		CheckNoRow("IF NOT EXISTS(SELECT * FROM #test WHERE i = 6 AND c = 'foo') SELECT 1");
	}
}
コード例 #18
0
ファイル: funccall.c プロジェクト: DavidRueter/freetds
int
main(int argc, char *argv[])
{
	SQLINTEGER input, output;
	SQLLEN ind, ind2, ind3, ind4;
	SQLINTEGER out1;
	char out2[30];

	odbc_connect();

	odbc_command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");

	odbc_command("create proc simpleresult @i int as begin return @i end");

	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

	CHKPrepare(T("{ \n?\t\r= call simpleresult(?)}"), SQL_NTS, "S");

	input = 123;
	ind2 = sizeof(input);
	output = 0xdeadbeef;
	CHKExecute("S");

	if (output != 123) {
		printf("Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	if (SQLFetch(odbc_stmt) != SQL_ERROR) {
		printf("Data not expected\n");
		exit(1);
	}
	ODBC_CHECK_COLS(0);

	/* just to reset some possible buffers */
	odbc_command("DECLARE @i INT");

	/* same test but with SQLExecDirect and same bindings */
	input = 567;
	ind2 = sizeof(input);
	output = 0xdeadbeef;
	CHKExecDirect(T("{?=call simpleresult(?)}"), SQL_NTS, "S");

	if (output != 567) {
		fprintf(stderr, "Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	CHKFetch("E");

	odbc_command("drop proc simpleresult");

	odbc_command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");

	/* force cursor close */
	SQLCloseCursor(odbc_stmt);

	/* test output parameter */
	odbc_command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");

	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind,  "S");
	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2, "S");
	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &out1,   0,            &ind3, "S");
	CHKBindParameter(4, SQL_PARAM_OUTPUT, SQL_C_CHAR,  SQL_VARCHAR, 20, 0, out2,    sizeof(out2), &ind4, "S");

	CHKPrepare(T("{ \n?\t\r= call simpleresult2(?,?,?)}"), SQL_NTS, "S");

	input = 987;
	ind2 = sizeof(input);
	out1 = 888;
	output = 0xdeadbeef;
	ind3 = SQL_DATA_AT_EXEC;
	ind4 = SQL_DEFAULT_PARAM;
	strcpy(out2, "bad!");
	CHKExecute("S");

	if (output != 987 || ind3 <= 0 || ind4 <= 0 || out1 != 6789 || strcmp(out2, "test foo") != 0) {
		printf("ouput = %d ind3 = %d ind4 = %d out1 = %d out2 = %s\n", (int) output, (int) ind3, (int) ind4, (int) out1,
		       out2);
		printf("Invalid result\n");
		exit(1);
	}

	/* should return "Invalid cursor state" */
	CHKFetch("E");

	ODBC_CHECK_COLS(0);

	odbc_command("drop proc simpleresult2");

	/*
	 * test from shiv kumar
	 * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
	 * SQLBindParameter call is not working on AIX"
	 */
	odbc_command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");

	odbc_reset_statement();

	odbc_command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
	SQLCloseCursor(odbc_stmt);

	CHKPrepare(T("{ ? = CALL rpc_read ( ?, ? ) }"), SQL_NTS, "S");

	ind = 0;
	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

	ind2 = 0;
	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");

	ind3 = 8;
	CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3, "S");

	CHKExecute("S");

	CHKFetch("S");

	CHKFetch("No");

	odbc_reset_statement();
	odbc_command("drop proc rpc_read");

	/*
	 * Test from Joao Amaral
	 * This test SQLExecute where a store procedure returns no result
	 * This seems similar to a previous one but use set instead of select
	 * (with is supported only by mssql and do not return all stuff as 
	 * select does)
	 */
	if (odbc_db_is_microsoft()) {

		odbc_reset_statement();

		odbc_command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
		odbc_command("create proc sp_test @res int output as set @res = 456");

		odbc_reset_statement();

		CHKPrepare(T("{ call sp_test(?)}"), SQL_NTS, "S");
		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");

		output = 0xdeadbeef;
		CHKExecute("S");

		if (output != 456) {
			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
			return 1;
		}
		odbc_command("drop proc sp_test");
	}
	odbc_disconnect();

	if (odbc_db_is_microsoft())
		test_with_conversions();

	printf("Done.\n");
	return 0;
}
コード例 #19
0
ファイル: scroll.c プロジェクト: DmitrySigaev/ncbi
int
main(int argc, char *argv[])
{
#define ROWS 3
#define C_LEN 10

	SQLUINTEGER n[ROWS];
	char c[ROWS][C_LEN];
	SQLLEN c_len[ROWS], n_len[ROWS];

	SQLUSMALLINT statuses[ROWS];
	SQLUSMALLINT i;
	SQLULEN num_row;
	int i_test;

	typedef struct _test
	{
		SQLUSMALLINT type;
		SQLINTEGER irow;
		int start;
		int num;
	} TEST;

	static const TEST tests[] = {
		{SQL_FETCH_NEXT, 0, 1, 3},
		{SQL_FETCH_NEXT, 0, 4, 2},
		{SQL_FETCH_PRIOR, 0, 1, 3},
		{SQL_FETCH_NEXT, 0, 4, 2},
		{SQL_FETCH_NEXT, 0, -1, -1},
		{SQL_FETCH_FIRST, 0, 1, 3},
		{SQL_FETCH_ABSOLUTE, 3, 3, 3},
		{SQL_FETCH_RELATIVE, 1, 4, 2},
		{SQL_FETCH_LAST, 0, 3, 3}
	};
	const int num_tests = sizeof(tests) / sizeof(TEST);

	odbc_use_version3 = 1;

	odbc_connect();
	odbc_check_cursor();

	/* create test table */
	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
	odbc_command("CREATE TABLE #test(i int, c varchar(6))");
	odbc_command("INSERT INTO #test(i, c) VALUES(1, 'a')");
	odbc_command("INSERT INTO #test(i, c) VALUES(2, 'bb')");
	odbc_command("INSERT INTO #test(i, c) VALUES(3, 'ccc')");
	odbc_command("INSERT INTO #test(i, c) VALUES(4, 'dddd')");
	odbc_command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')");

	/* set cursor options */
	odbc_reset_statement();
	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S");
	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");

	/* */
	CHKExecDirect(T("SELECT i, c FROM #test"), SQL_NTS, "S");

	/* bind some rows at a time */
	CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S");
	CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S");

	for (i_test = 0; i_test < num_tests; ++i_test) {
		const TEST *t = &tests[i_test];

		printf("Test %d\n", i_test + 1);

		if (t->start == -1) {
			CHKFetchScroll(t->type, t->irow, "No");
		} else {
			CHKFetchScroll(t->type, t->irow, "S");

			if (t->start < 1) {
				fprintf(stderr, "Rows not expected\n");
				exit(1);
			}

			/* print, just for debug */
			for (i = 0; i < num_row; ++i)
				printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]);
			printf("---\n");

			if (num_row != t->num) {
				fprintf(stderr, "Expected %d rows, got %d\n", t->num, (int) num_row);
				exit(1);
			}

			for (i = 0; i < num_row; ++i) {
				char name[10];

				memset(name, 0, sizeof(name));
				memset(name, 'a' - 1 + i + t->start, i + t->start);
				if (n[i] != i + t->start || c_len[i] != strlen(name) || strcmp(c[i], name) != 0) {
					fprintf(stderr, "Wrong row returned\n");
					fprintf(stderr, "\tn %d %d\n", (int) n[i], i + t->start);
					fprintf(stderr, "\tc len %d %d\n", (int) c_len[i], (int) strlen(name));
					fprintf(stderr, "\tc %s %s\n", c[i], name);
					exit(1);
				}
			}
		}
	}

	odbc_reset_statement();

	odbc_disconnect();
	return 0;
}
コード例 #20
0
ファイル: rowset.c プロジェクト: Distrotech/freetds
int
main(int argc, char *argv[])
{
	int i;
	SQLLEN len;
#ifdef HAVE_SQLROWSETSIZE
	SQLROWSETSIZE row_count;
#else
	SQLULEN row_count;
#endif
	SQLUSMALLINT statuses[10];
	char buf[32];

	odbc_use_version3 = 1;
	odbc_connect();

	/* initial value should be 1 */
	CHKGetStmtAttr(SQL_ROWSET_SIZE, &len, sizeof(len), NULL, "S");
	if (len != 1) {
		fprintf(stderr, "len should be 1\n");
		odbc_disconnect();
		return 1;
	}

	/* check invalid parameter values */
	test_err(-123);
	test_err(-1);
	test_err(0);

	odbc_check_cursor();

	/* set some correct values */
	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0, "S");
	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S");

	/* now check that SQLExtendedFetch works as expected */
	odbc_command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
	for (i = 0; i < 10; ++i) {
		char s[10];
		char sql[128];

		memset(s, 'a' + i, 9);
		s[9] = 0;
		sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s);
		odbc_command(sql);
	}

	odbc_reset_statement();
	CHKSetStmtOption(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, "S");
	CHKExecDirect((SQLCHAR *) "SELECT * FROM #rowset ORDER BY n", SQL_NTS, "SI");

	CHKBindCol(2, SQL_C_CHAR, buf, sizeof(buf), &len, "S");

	row_count = 0xdeadbeef;
	memset(statuses, 0x55, sizeof(statuses));
	CHKExtendedFetch(SQL_FETCH_NEXT, 1, &row_count, statuses, "S");

	if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) {
		fprintf(stderr, "Invalid result\n");
		odbc_disconnect();
		return 1;
	}

	odbc_disconnect();

	printf("Done.\n");
	return 0;
}
コード例 #21
0
ファイル: moreandcount.c プロジェクト: DavidRueter/freetds
static void
DoTest(int prepare)
{
	int n = 0;
	static const char query[] =
		/* on prepared this recordset should be skipped */
		"DECLARE @b INT SELECT @b = 25 "
		"SELECT * FROM #tmp1 WHERE i <= 3 "
		/* on prepare we cannot distinguish these recordset */
		"INSERT INTO #tmp2 SELECT * FROM #tmp1 WHERE i = 1 "
		"INSERT INTO #tmp2 SELECT * FROM #tmp1 WHERE i <= 3 "
		"SELECT * FROM #tmp1 WHERE i = 1 "
		/* but FreeTDS can detect last recordset */
		"UPDATE #tmp1 SET i=i+1 WHERE i >= 2";

	if (prepare) {
		CHKPrepare(T(query), SQL_NTS, "S");
		CHKExecute("S");
	} else {

		/* execute a batch command select insert insert select and check rows */
		CHKExecDirect(T(query), SQL_NTS, "S");
	}
	if (!prepare) {
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
	}
	printf("Result %d\n", ++n);
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("S");
	CHKFetch("S");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("No");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(2);
	CHKMoreResults("S");
	if (!prepare) {
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
		printf("Result %d\n", ++n);
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(2);
		CHKMoreResults("S");
	}
	printf("Result %d\n", ++n);
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("S");
	ODBC_CHECK_COLS(1);
	ODBC_CHECK_ROWS(-1);
	CHKFetch("No");
	ODBC_CHECK_COLS(1);
	if (prepare) {
		/* collapse 2 recordset... after a lot of testing this is the behavior! */
		if (odbc_driver_is_freetds())
			ODBC_CHECK_ROWS(2);
	} else {
		ODBC_CHECK_ROWS(1);
		CHKMoreResults("S");
		ODBC_CHECK_COLS(0);
		ODBC_CHECK_ROWS(2);
	}

	CHKMoreResults("No");
#ifndef TDS_NO_DM
	if (!prepare)
		ODBC_CHECK_COLS(-1);
	ODBC_CHECK_ROWS(-2);
#endif
	ODBC_FREE();
}