示例2:行集的定位与操作¶
此示例显示了使用SQLSetPos对行集中指定行进行定位更新删除插入操作。示例使用的行集大小为10,存放数据的数组大小为11,其中前10行用于放置获取的行集数据,第11行用于放置插入操作使用的新数据。
#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
SQLINTEGER UserIDArray[ROW_ARRAY_SIZE + 1];
SQLCHAR UserNameArray[ROW_ARRAY_SIZE + 1] [MAX_STR_LEN];
SQLINTEGER UserIDIndArray[ROW_ARRAY_SIZE + 1],
UserNameIndArray[ROW_ARRAY_SIZE + 1];
SQLUSMALLINT RowStatusArray[10], RowNum, Action;
RETCODE retcode;
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;
SQLCHAR errmsg[10];
SQLINTEGER errint;
SQLSMALLINT errind;
SQLCHAR errdesc[512];
int errLineNum = 0 ;
int GetAction(SQLUSMALLINT *a,SQLUSMALLINT *b)
{
*a = 0;
*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);
// 设置游标类型
// 设置结果集绑定方式
// 设置游标行集的大小
// 设置存放行集每一行数据读取情况的状态矩阵
SQLSetStmtAttr(hstmt1, SQL_ATTR_CURSOR_TYPE,
(SQLPOINTER)SQL_CURSOR_KEYSET_DRIVEN, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_BIND_TYPE,
SQL_BIND_BY_COLUMN, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE,
(SQLPOINTER)ROW_ARRAY_SIZE, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);
// 绑定结果集
SQLBindCol(hstmt1, 1, SQL_C_SLONG, UserIDArray, 0, UserIDIndArray);
SQLBindCol(hstmt1, 2, SQL_C_CHAR, UserNameArray,
sizeof(UserNameArray[0]),UserNameIndArray);
// 执行SQL语句
SQLExecDirect(hstmt1, (SQLCHAR*)"SELECT ID, USER_NAME FROM Users",
SQL_NTS);
// 移动游标获取一个行集
retcode = SQLFetchScroll(hstmt1, SQL_FETCH_NEXT, 0);
// 应用程序获取用户需要的SQLSetPos操作类型和要操作的行的编号
if (GetAction(&Action, &RowNum))
{
switch (Action) {
case SQL_POSITION:
retcode = SQLSetPos(hstmt1, RowNum, SQL_POSITION,
SQL_LOCK_NO_CHANGE);
break;
case SQL_UPDATE:
// 重新填充行集中指定行的绑定缓冲区并执行UPDATE
GetNewData(&UserIDArray[RowNum - 1], &UserIDIndArray[RowNum - 1],
UserNameArray[RowNum - 1], &UserNameIndArray[RowNum - 1]);
SQLSetPos(hstmt1, RowNum, SQL_UPDATE, SQL_LOCK_NO_CHANGE);
break;
case SQL_DELETE:
// 删除指定行
SQLSetPos(hstmt1, RowNum, SQL_DELETE, SQL_LOCK_NO_CHANGE);
break;
case SQL_ADD:
// 使用绑定数组的额外元素执行插入操作
GetNewData(&UserIDArray[10], &UserIDIndArray[10],UserNameArray[10],
&UserNameIndArray[10]);
retcode = SQLSetPos(hstmt1, 11, SQL_ADD, SQL_LOCK_NO_CHANGE);
break;
}
if (SQL_NO_DATA!=SQLGetDiagRec(SQL_HANDLE_STMT, hstmt1, ++errLineNum,
errmsg, &errint, (SQLCHAR *)errdesc, (SQLSMALLINT)500, &errind))
{
printf("%s: %sn", errmsg, errdesc);
printf("n");
char c =getchar();
}
}
// Close the cursor.
SQLCloseCursor(hstmt1);
// 释放语句句柄
// 断开连接
// 释放连接句柄和环境句柄
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}