1 /* Test sp_cursorprepare / sp_cursorexecute usage to support SELECT FOR UPDATE
2  * This test compiles and works fine with SQL Server Native Client, and uses
3  * the sp_cursor* API Server Cursors ...
4  */
5 
6 #include "common.h"
7 
8 #include <common/test_assert.h>
9 
10 static void
exec_direct(const char * stmt)11 exec_direct(const char *stmt)
12 {
13 	SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
14 
15 	CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_conn, (SQLHANDLE *) & odbc_stmt, "S");
16 	odbc_command(stmt);
17 	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
18 }
19 
20 int
main(int argc,char ** argv)21 main(int argc, char **argv)
22 {
23 	char buff[64];
24 	SQLLEN ind;
25 
26 	odbc_use_version3 = 1;
27 	odbc_connect();
28 
29 	odbc_check_cursor();
30 
31 	exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
32 	exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')");
33 
34 	odbc_reset_statement();
35 
36 	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S");
37 
38 	CHKSetCursorName(T("c112"), SQL_NTS, "S");
39 
40 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_OFF), 0, "S");
41 
42 	CHKPrepare(T("SELECT * FROM #t1 FOR UPDATE"), SQL_NTS, "S");
43 
44 	CHKExecute("S");
45 
46 	CHKFetch("S");
47 
48 	exec_direct("UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
49 
50 	CHKCloseCursor("SI");
51 
52 	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S");
53 
54 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(SQL_AUTOCOMMIT_ON), 0, "S");
55 
56 	CHKExecDirect(T("SELECT c FROM #t1 WHERE k = 1"), SQL_NTS, "S");
57 
58 	CHKFetch("S");
59 
60 	CHKGetData(1, SQL_C_CHAR, buff, sizeof(buff), &ind, "S");
61 
62 	printf(">> New value after update = [%s] (should be [xxx]) \n", buff);
63 
64 	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
65 	odbc_stmt = SQL_NULL_HSTMT;
66 
67 	odbc_disconnect();
68 
69 	return 0;
70 }
71