ODBC编程中获取SQL操作结果
ODBC编程中获取SQL操作结果

ODBC编程中获取SQL操作结果

在使用了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;
        }
    }
starry0214

订阅评论
提醒
guest

0 评论
最新
最旧 最多投票
内联反馈
查看所有评论