示例3:使用书签¶
使用书签的行集提取¶
此示例显示使用SQLFetchSroll并设置 FetchOrientation为SQL_FETCH_BOOKMARK的行集提取操作。
#include <string.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <odbcss.h>
#include <stdio.h>
#define ROW_ARRAY_SIZE 10
SQLUINTEGER NumRowsFetched;
SQLUSMALLINT RowStatusArray[ROW_ARRAY_SIZE];
SQLCHAR BookMark[10];
RETCODE retcode;
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;
int main()
{
// 分配ODBC环境句柄
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
// 指定应用程序ODBC版本
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER)
SQL_OV_ODBC3, SQL_IS_INTEGER);
// 分配ODBC连接句柄并连接
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
retcode = SQLConnect(hdbc1,(SQLCHAR*)"OSRDBSource",
SQL_NTS,(SQLCHAR*)"sysdba", SQL_NTS,
(SQLCHAR*)"szoscar55",SQL_NTS);
// 分配语句句柄
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);
// 设置游标类型
// 设置游标行集的大小
// 设置存放行集实际获取的行数的程序变量
// 设置存放行集每一行数据读取情况的状态矩阵
// 设置使用变长书签
// 设置存放书签的程序变量
SQLSetStmtAttr(hstmt1, SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE,
(SQLPOINTER)ROW_ARRAY_SIZE, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROWS_FETCHED_PTR, &NumRowsFetched,
0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_USE_BOOKMARKS,
(SQLPOINTER)SQL_UB_VARIABLE, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_FETCH_BOOKMARK_PTR,
(SQLPOINTER)BookMark, 0);
// 执行SQL语句
SQLExecDirect(hstmt1, (SQLCHAR*)"SELECT ID, USER_NAME FROM USERS",
SQL_NTS);
// 获取任意行的书签,此处实际获取的是结果集第6行的书签
SQLFetchScroll(hstmt1, SQL_FETCH_NEXT, 0);
SQLSetPos(hstmt1, 6, SQL_POSITION, SQL_LOCK_NO_CHANGE);
SQLGetData(hstmt1, 0, SQL_C_CHAR, (SQLPOINTER)BookMark, 10, NULL);
// 使用SQL_FETCH_BOOKMARK,获取从书签指定的行开始的行集
SQLFetchScroll(hstmt1, SQL_FETCH_BOOKMARK, 0);
// Close the cursor.
SQLCloseCursor(hstmt1);
// 释放语句句柄
// 断开连接
// 释放连接句柄和环境句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
使用书签的批量操作¶
此示例显示使用SQLBulkOperation并借助书签的批量操作。示例先获取一个大小为10的行集的游标,之后对行集中的偶数行进行FETCH/UPDATE/DELETE操作。
#include <string.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <odbcss.h>
#include <stdio.h>
#define MAX_STR_LEN 65
#define ROW_ARRAY_SIZE 10
typedef struct tagBookmarkStruct {
SQLCHAR Bookmark[10];
SQLINTEGER BookmarkLen;
}BookmarkStruct;
typedef struct tagUserStruct {
SQLCHAR Bookmark[10];
SQLINTEGER BookmarkLen;
SQLINTEGER UserID;
SQLINTEGER UserIDInd;
SQLCHAR UserName[MAX_STR_LEN];
SQLINTEGER UserNameInd;
} UserStruct;
SQLUINTEGER NumRowsFetched;
BookmarkStruct BookmarkArray[ROW_ARRAY_SIZE];
UserStruct UserArray[ROW_ARRAY_SIZE/2];
SQLUSMALLINT RowStatusArray[10], Action, RowNum,i;
RETCODE retcode;
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;
int GetAction(SQLUSMALLINT *a,SQLUSMALLINT *b)
{
*a = 4;
*b = 1;
return 1;
}
int GetNewData(SQLINTEGER *a,SQLINTEGER *b,SQLCHAR *c,SQLINTEGER *d)
{
*a = 11;
*b = 0;
*d = -3;
strcpy((char*)c ,"fsggfs");
return 1;
}
int main()
{
// 分配ODBC环境句柄
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
// 指定应用程序ODBC版本
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER)
SQL_OV_ODBC3, SQL_IS_INTEGER);
// 分配ODBC连接句柄并连接
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
retcode = SQLConnect(hdbc1,(SQLCHAR*)"OSRDBSource",
SQL_NTS,(SQLCHAR*)"sysdba", SQL_NTS,
(SQLCHAR*)"szoscar55",SQL_NTS);
// 分配语句句柄
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);
// 设置游标类型
// 设置绑定模式为row-wise
// 设置游标行集的大小
// 设置存放行集实际获取的行数的程序变量
// 设置存放行集每一行数据读取情况的状态矩阵
// 设置使用变长书签
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0);
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_BIND_TYPE,
(SQLPOINTER)SQL_BIND_TYPE_DEFAULT, 0);
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE,
(SQLPOINTER)ROW_ARRAY_SIZE, 0);
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROWS_FETCHED_PTR,
&NumRowsFetched, 0);
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_STATUS_PTR,
RowStatusArray, 0);
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_USE_BOOKMARKS,
(SQLPOINTER)SQL_UB_VARIABLE, 0);
// 执行SQL语句
retcode = SQLExecDirect(hstmt1, (SQLCHAR*)"SELECT ID, USER_NAME FROM
USERS", SQL_NTS);
/****** 获取批量操作使用的书签******/
retcode = SQLBindCol(hstmt1, 0, SQL_C_VARBOOKMARK,
BookmarkArray[0].Bookmark,
sizeof(BookmarkArray[0].Bookmark), &BookmarkArray[0].BookmarkLen);
retcode = SQLFetchScroll(hstmt1, SQL_FETCH_NEXT, 0);
/****** 执行批量操作******/
// 设置批量操作的行数
retcode = SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE,
(SQLPOINTER)(ROW_ARRAY_SIZE/2), 0);
// 重新绑定结果集缓存
retcode = SQLBindCol(hstmt1, 0, SQL_C_VARBOOKMARK,
UserArray[0].Bookmark,sizeof(UserArray[0].Bookmark),
&UserArray[0].BookmarkLen);
retcode = SQLBindCol(hstmt1, 1, SQL_C_ULONG, &UserArray[0].UserID, 0,
&UserArray[0].UserIDInd);
retcode = SQLBindCol(hstmt1, 2, SQL_C_CHAR, UserArray[0].UserName,
sizeof(UserArray[0].UserName),&UserArray[0].UserNameInd);
// 应用程序获取用户需要的SQLBulkOperation操作类型
if (GetAction(&Action, &RowNum))
{
switch (Action) {
case SQL_ADD:
for ( i = 0; i < ROW_ARRAY_SIZE/2; i ++)
{
// 重新填充行集中指定行的绑定缓冲区
GetNewData(&UserArray[i].UserID, &UserArray[i].UserIDInd ,
UserArray[i].UserName, &UserArray[i].UserNameInd);
// SQL_ADD操作不需要使用书签
}
retcode = SQLBulkOperations(hstmt1, SQL_ADD);
break;
case SQL_FETCH_BY_BOOKMARK:
for (i = 0; i < ROW_ARRAY_SIZE/2; i ++)
{
// 获取该行对应的书签
memcpy(UserArray[i].Bookmark, BookmarkArray[2*i].Bookmark,
BookmarkArray[2*i].BookmarkLen);
}
SQLBulkOperations(hstmt1, SQL_FETCH_BY_BOOKMARK);
break;
case SQL_DELETE_BY_BOOKMARK:
for (i = 0; i < ROW_ARRAY_SIZE/2; i ++)
{
// 获取该行对应的书签
memcpy(UserArray[i].Bookmark, BookmarkArray[2*i].Bookmark,
BookmarkArray[2*i].BookmarkLen);
}
SQLBulkOperations(hstmt1, SQL_DELETE_BY_BOOKMARK);
case SQL_UPDATE_BY_BOOKMARK:
for (i = 0; i < ROW_ARRAY_SIZE/2; i ++)
{
// 重新填充行集中指定行的绑定缓冲区
GetNewData(&UserArray[i].UserID, &UserArray[i].UserIDInd ,
UserArray[i].UserName, &UserArray[i].UserNameInd);
// 获取该行对应的书签
memcpy(UserArray[i].Bookmark, BookmarkArray[2*i].Bookmark,
BookmarkArray[2*i].BookmarkLen);
}
SQLBulkOperations(hstmt1, SQL_UPDATE_BY_BOOKMARK);
break;
}
}
// 关闭游标
SQLFreeStmt(hstmt1, SQL_CLOSE);
// 释放语句句柄
// 断开连接
// 释放连接句柄和环境句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}