在使用了select操作后,往往需要获取结果集,这里有几个相关的函数:SQLGetData
、SQLBindCol
、SQLFetch()
。SQLFetch()
函数是用于获取结果集中的一行数据。
大致情况下,SQLFetch() 函数获取结果数据有三种方式:
1. 基于SQLGetData 函数
2. 基于SQLBindCol 函数
3. SQLBindCol 和 SQLGetData 函数结合。
1. 基于SQLGetData 函数
简单来说使用 SQLGetData 时,每调用一次 SQLFetch函数获取的结果集,就调用 SQLGetData 获取指定列的值。
SQLRETURN SQLGetData(
SQLHSTMT StatementHandle,
//[输入]语句句柄。
SQLUSMALLINT Col_or_Param_Num,
//[输入]对于检索列数据,它是要为其返回数据的列的编号。 结果集列以从 1 开始的递增列顺序进行编号。
SQLSMALLINT TargetType,
//[输入]该列的数据类型
SQLPOINTER TargetValuePtr,
//[输出] 存储该列的结果值变量,指针
SQLLEN BufferLength,
//[输入]指定结果数据的大小(以字节为单位)
SQLLEN * StrLen_or_IndPtr
//[输出]返回获取的结果的大小,指针
);
示例代码:
#define NAME_LEN 50
#define PHONE_LEN 50
SQLCHAR szName[NAME_LEN], szPhone[PHONE_LEN];
SQLINTEGER sCustID, cbName, cbAge, cbBirthday;
SQLRETURN retcode;
SQLHSTMT hstmt;
retcode = SQLExecDirect(hstmt,
"SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY 2, 1, 3",
SQL_NTS);
if (retcode == SQL_SUCCESS) {
while (TRUE) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
show_error();
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
/* Get data for columns 1, 2, and 3 */
SQLGetData(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);
SQLGetData(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);
SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN,
&cbPhone);
/* Print the row of data */
fprintf(out, "%-5d %-*s %*s", sCustID, NAME_LEN-1, szName,
PHONE_LEN-1, szPhone);
} else {
break;
}
}
}
在使用SQLGetData
函数时,推荐使用下列写法:(避免因为参数错误导致结果被截断)
/* 获取数据 */
SQLCHAR str[row][column]; //row为当前查询结果中,有多少列数据,column为每列数据的长度
SQLLEN* len_str[10];
for (int i = 0; i < 10; i++) {
memset(str[i], 0, 50);
len_str[i] = new SQLLEN;
}
for (int i = 0; i < 10; i++)
{
SQLGetData(hstmt, i + 1, SQL_C_CHAR, str[i], 50, len_str[i]);
}
/*上述代码执行完后,能将一行查询结果存入str二维数组中,如果想存储多行数据,则在此代码外加一个while循环,并使用SQLFetch(hstmt);跳转查询指针。*/
while (true)
{
ret = SQLFetch(hstmt);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
/*代码*/
}
else {
break;
}
}
2. 基于SQLBindCol 函数
在获取结果集之前,应用程序使用SQLBindCol
将结果集中的每一列绑定到一个程序变量。如果结果集列和程序变量具有不同的数据类型,则驱动程序处理数据转换。如果应用程序的SQL_ATTR_ROW_ARRAY_SIZE
设置大于1,它可以将结果列绑定到变量数组,这些变量将在每次调用SQLFetchScroll
时全部填充。
也就是说使用 SQLBindCol
函数,需要先调用SQLBindCol 函数把要操作的列数据绑定到变量上,然后再使用 SQLFetch 函数进行遍历。
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
//[输入]语句句柄。
SQLUSMALLINT ColumnNumber,
//[输入]要绑定的结果集列的数目。 列按从 0 开始的递增列顺序进行编号,其中列 0 是书签列。
// 如果未使用书签(即,SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_OFF),则列号从 1 开始。
SQLSMALLINT TargetType,
//[输入]该列的数据类型
SQLPOINTER TargetValuePtr,
//[输出] 存储该列的结果值变量,指针
SQLLEN BufferLength,
//[输入]指定结果数据的大小(以字节为单位)
SQLLEN * StrLen_or_Ind
//[输出]返回获取的结果的大小,指针
);
示例代码:
// 1、绑定第1,2,3列
SQLCHAR id[32], user[255], pwd[255];
SQLLEN Strlen_or_IndPtr = 0;
res = SQLBindCol(myStatementHandle, 1, SQL_C_CHAR, &id, 32, &Strlen_or_IndPtr);
res = SQLBindCol(myStatementHandle, 2, SQL_C_CHAR, &user, 255, &Strlen_or_IndPtr);
res = SQLBindCol(myStatementHandle, 3, SQL_C_CHAR, &pwd, 255, &Strlen_or_IndPtr);
// 展示第1,2,3列的每一行数据
for (int i = 0;; i++)
{
res = SQLFetch(myStatementHandle); // 获取结果
if (res == SQL_ERROR || res == SQL_SUCCESS_WITH_INFO)
break;
if (res == SQL_SUCCESS || res == SQL_SUCCESS_WITH_INFO)
cout << i + 1 << " -- " << id<< " -- " << user<< " -- " << pwd<< " -- " << Strlen_or_IndPtr << endl; // 进行展示
else
{
cout << res;
break;
}
}