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 static void
exec_direct(const char * stmt)9 exec_direct(const char *stmt)
10 {
11 SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
12
13 CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_conn, (SQLHANDLE *) & odbc_stmt, "S");
14 odbc_command(stmt);
15 CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
16 }
17
18 int
main(int argc,char ** argv)19 main(int argc, char **argv)
20 {
21 char buff[64];
22 SQLLEN ind;
23
24 odbc_use_version3 = 1;
25 odbc_connect();
26
27 odbc_check_cursor();
28
29 exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
30 exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')");
31
32 odbc_reset_statement();
33
34 CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S");
35
36 CHKSetCursorName(T("c112"), SQL_NTS, "S");
37
38 CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, TDS_INT2PTR(SQL_AUTOCOMMIT_OFF), 0, "S");
39
40 CHKPrepare(T("SELECT * FROM #t1 FOR UPDATE"), SQL_NTS, "S");
41
42 CHKExecute("S");
43
44 CHKFetch("S");
45
46 exec_direct("UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
47
48 CHKCloseCursor("SI");
49
50 CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S");
51
52 CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, TDS_INT2PTR(SQL_AUTOCOMMIT_ON), 0, "S");
53
54 CHKExecDirect(T("SELECT c FROM #t1 WHERE k = 1"), SQL_NTS, "S");
55
56 CHKFetch("S");
57
58 CHKGetData(1, SQL_C_CHAR, buff, sizeof(buff), &ind, "S");
59
60 printf(">> New value after update = [%s] (should be [xxx]) \n", buff);
61
62 CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
63 odbc_stmt = SQL_NULL_HSTMT;
64
65 odbc_disconnect();
66
67 return 0;
68 }
69