Mysql使用SQLFetch()获取结果数据 - 基于 SQLBindCol

SQLFetch() 函数获取结果数据有三种方式:

1. 基于SQLBindCol 函数

2. 基于SQLGetData 函数

3. SQLBindCol 和 SQLGetData 函数结合。

基于SQLGetData 函数的方法参见: Mysql使用SQLFetch()获取结果数据 - 基于 SQLGetData

目录

1. 参数简介

2. 代码示例:

2.1 示例

2.2 结果:

3. 其他C类型名称(不全,详情查看sqlext.h): 

4. SQLBindCol 函数参数详细说明,摘自MSDN。

1. 函数和参数简介

        在获取结果集之前,应用程序使用SQLBindCol将结果集中的每一列绑定到一个程序变量。在绑定了列之后,每次应用程序调用SQLFetch或SQLFetchScroll时,驱动程序都会将当前行的数据传输到与结果集列绑定的变量中。如果结果集列和程序变量具有不同的数据类型,则驱动程序处理数据转换。如果应用程序的SQL_ATTR_ROW_ARRAY_SIZE设置大于1,它可以将结果列绑定到变量数组,这些变量将在每次调用SQLFetchScroll时全部填充。

        也就是说使用 SQLBindCol 函数,需要先调用SQLBindCol 函数把要操作的列数据绑定到变量上,然后再使用 SQLFetch 函数进行遍历。

SQLRETURN SQLBindCol(
     SQLHSTMT     StatementHandle,       // [Input]
     SQLUSMALLINT     ColumnNumber,      // [Input]
     SQLSMALLINT     TargetType,         // [Input]
     SQLPOINTER     TargetValuePtr,      // [Deferred Input/Output]
          SQLLEN     BufferLength,       // [Input]
     SQLLEN *     StrLen_or_Ind          // [Deferred Input/Output]
);

简单的来说:

参数1:操作的句柄。

参数2:要进行操作的列号,从1开始

参数3:该列的数据类型

参数4:存储该列的结果值变量

参数5:指定结果数据的大小

参数6:返回获取的结果的大小

具体参数释义见文末,摘自MSDN。

2. 代码示例:

2.1 示例

 // 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;
        }
    }

【释】:

id[32], user[255], pwd[255] 变量和数据表的列对应,变量用户存储结果。如下图:

数据表

 注意:定义变量的时候一定要指定变量类型,不然以SQLPOINTER     定义变量时,结果为ASCII码,见下面的结果图2。

res = SQLBindCol(myStatementHandle, 1, SQL_C_CHAR, &id, 32, &Strlen_or_IndPtr);

 myStatementHandle:为句柄;

1:代表第 1 列;

SQL_C_CHAR:指定结果的数据类型,根据数据表中的定义来决定,其他C类型名称见文末;

id:保存结果变量;

32:指定结果的大小,注意要留出终止字符的空间;

Strlen_or_IndPtr:返回结果数据的大小。

2.2 结果:

结果图 1

 如果存储结果的指针定义成  SQLPOINTER  类型,则结果为ASCII值,见下图2。

结果图 2

3. 其他C类型名称 

(不全,详情查看sqlext.h)
#define SQL_C_CHAR    SQL_CHAR                 /* CHAR, VARCHAR, DECIMAL, NUMERIC */
#define SQL_C_LONG    SQL_INTEGER           /* INTEGER                      */
#define SQL_C_SHORT   SQL_SMALLINT        /* SMALLINT                     */
#define SQL_C_FLOAT   SQL_REAL                 /* REAL                         */
#define SQL_C_DOUBLE  SQL_DOUBLE         /* FLOAT, DOUBLE                */

4. SQLBindCol 函数参数详细说明

摘自MSDN。

(1) StatementHandle

[Input] Statement handle.
【释义】 语句句柄。

(2) ColumnNumber

[Input] Number of the result set column to bind. Columns are numbered in increasing column order starting at 0, where column 0 is the bookmark column. If bookmarks are not used — that is, the SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_OFF — then column numbers start at 1.
【释义】要绑定的结果集列的编号。列从0开始按列的递增顺序编号,其中列0是书签列。如果不使用书签,即SQL_ATTR_USE_BOOKMARKS语句属性被设置为SQL_UB_OFF,那么列号从1开始。

(3) TargetType

[Input] The identifier of the C data type of the * TargetValuePtr buffer. When it is retrieving data from the data source with SQLFetch, SQLFetchScroll, SQLBulkOperations, or SQLSetPos, the driver converts the data to this type; when it sends data to the data source with SQLBulkOperations or SQLSetPos, the driver converts the data from this type. For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types.
If the TargetType argument is an interval data type, the default interval leading precision (2) and the default interval seconds precision (6), as set in the SQL_DESC_DATETIME_INTERVAL_PRECISION and SQL_DESC_PRECISION fields of the ARD, respectively, are used for the data. If the TargetType argument is SQL_C_NUMERIC, the default precision (driver-defined) and default scale (0), as set in the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the ARD, are used for the data. If any default precision or scale is not appropriate, the application should explicitly set the appropriate descriptor field by a call to SQLSetDescField or SQLSetDescRec.
【释义】
TargetValuePtr缓冲区的C数据类型的标识符。当它使用SQLFetch、SQLFetchScroll、SQLBulkOperations或SQLSetPos从数据源检索数据时,驱动程序将数据转换为这种类型;当它使用SQLBulkOperations或SQLSetPos将数据发送到数据源时,驱动程序将从这种类型转换数据。
如果TargetType参数是一个间隔数据类型,则使用ARD的SQL_DESC_DATETIME_INTERVAL_PRECISION和SQL_DESC_PRECISION字段中分别设置的默认间隔超前精度(2)和默认间隔秒精度(6)。如果TargetType参数为SQL_C_NUMERIC,则使用ARD的SQL_DESC_PRECISION和SQL_DESC_SCALE字段中设置的默认精度(驱动程序定义的)和默认scale(0)。如果任何默认的精度或比例不合适,应用程序应该通过调用SQLSetDescField或SQLSetDescRec显式设置适当的描述符字段。

(4) TargetValuePtr

[Deferred Input/Output] Pointer to the data buffer to bind to the column. SQLFetch and SQLFetchScroll return data in this buffer. SQLBulkOperations returns data in this buffer when Operation is SQL_FETCH_BY_BOOKMARK; it retrieves data from this buffer when Operation is SQL_ADD or SQL_UPDATE_BY_BOOKMARK. SQLSetPos returns data in this buffer when Operation is SQL_REFRESH; it retrieves data from this buffer when Operation is SQL_UPDATE.
If TargetValuePtr is a null pointer, the driver unbinds the data buffer for the column. An application can unbind all columns by calling SQLFreeStmt with the SQL_UNBIND option. An application can unbind the data buffer for a column but still have a length/indicator buffer bound for the column, if the TargetValuePtr argument in the call to SQLBindCol is a null pointer but the StrLen_or_IndPtr argument is a valid value.
【释义】
指向要绑定到列的数据缓冲区的指针。SQLFetch和SQLFetchScroll返回这个缓冲区中的数据。当操作为SQL_FETCH_BY_BOOKMARK时,SQLBulkOperations返回该缓冲区中的数据;当操作为SQL_ADD或SQL_UPDATE_BY_BOOKMARK时,从该缓冲区检索数据。当操作为SQL_REFRESH时,SQLSetPos返回该缓冲区中的数据;当操作为SQL_UPDATE时,它从这个缓冲区检索数据。
如果TargetValuePtr是空指针,驱动程序解除对列的数据缓冲区的绑定。应用程序可以通过使用SQL_UNBIND选项调用SQLFreeStmt来解除所有列的绑定。如果调用SQLBindCol的TargetValuePtr参数是一个空指针,但StrLen_or_IndPtr参数是一个有效值,应用程序可以解除对列的数据缓冲区的绑定,但仍然为列绑定了一个长度/指示器缓冲区。

(5) BufferLength

[Input] Length of the * TargetValuePtr buffer in bytes.
The driver uses BufferLength to avoid writing past the end of the * TargetValuePtr buffer when it returns variable-length data, such as character or binary data. Notice that the driver counts the null-termination character when it returns character data to * TargetValuePtr. * TargetValuePtr must therefore contain space for the null-termination character or the driver will truncate the data.
When the driver returns fixed-length data, such as an integer or a date structure, the driver ignores BufferLength and assumes the buffer is large enough to hold the data. Therefore, it is important for the application to allocate a large enough buffer for fixed-length data or the driver will write past the end of the buffer.
SQLBindCol returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength is 0. However, if TargetType specifies a character type, an application should not set BufferLength to 0, because ISO CLI–compliant drivers return SQLSTATE HY090 (Invalid string or buffer length) in that case.
【释义】 *TargetValuePtr缓冲区的长度,以字节为单位。
驱动程序使用BufferLength来避免在返回变长数据(如字符或二进制数据)时写入超过*TargetValuePtr缓冲区的末尾。注意,当驱动程序返回字符数据到*TargetValuePtr时,它会计数null终止字符。因此,TargetValuePtr必须包含空终止字符的空间,否则驱动程序将截断数据。
当驱动程序返回固定长度的数据时,例如一个整数或一个日期结构,驱动程序忽略BufferLength并假设缓冲区足够大以容纳数据。因此,对于应用程序来说,为固定长度的数据分配一个足够大的缓冲区是很重要的,否则驱动程序将写入超过缓冲区末端的数据。
当BufferLength小于0时返回SQLSTATE HY090(无效字符串或缓冲区长度),但当BufferLength为0时不返回SQLSTATE HY090。然而,如果TargetType指定了一个字符类型,应用程序不应该将BufferLength设置为0,因为在这种情况下,符合ISO CLI–compliant的驱动程序返回SQLSTATE HY090(无效字符串或缓冲区长度)。

(6) StrLen_or_IndPtr

[Deferred Input/Output] Pointer to the length/indicator buffer to bind to the column. SQLFetch and SQLFetchScroll return a value in this buffer. SQLBulkOperations retrieves a value from this buffer when Operation is SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK. SQLBulkOperations returns a value in this buffer when Operation is SQL_FETCH_BY_BOOKMARK. SQLSetPos returns a value in this buffer when Operation is SQL_REFRESH; it retrieves a value from this buffer when Operation is SQL_UPDATE.
【释义】
指向要绑定到列的长度/指示器缓冲区的指针。SQLFetch和SQLFetchScroll返回该缓冲区中的一个值。当“操作”为SQL_ADD、SQL_UPDATE_BY_BOOKMARK或SQL_DELETE_BY_BOOKMARK时,SQLBulkOperations从缓冲区中检索一个值。当操作为SQL_FETCH_BY_BOOKMARK时,SQLBulkOperations在此缓冲区中返回一个值。当操作为SQL_REFRESH时,SQLSetPos返回一个值在这个缓冲区中;当Operation为SQL_UPDATE时,它从该缓冲区检索值
SQLFetch, SQLFetchScroll, SQLBulkOperations, and SQLSetPos can return the following values in the length/indicator buffer:
  • The length of the data available to return
  • SQL_NO_TOTAL
  • SQL_NULL_DATA
The application can put the following values in the length/indicator buffer for use with SQLBulkOperations or SQLSetPos:
  • The length of the data being sent
  • SQL_NTS
  • SQL_NULL_DATA
  • SQL_DATA_AT_EXEC
  • The result of the SQL_LEN_DATA_AT_EXEC macro
  • SQL_COLUMN_IGNORE
If the indicator buffer and the length buffer are separate buffers, the indicator buffer can return only SQL_NULL_DATA, whereas the length buffer can return all other values.
For more information, see SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function, and Using Length/Indicator Values.
If StrLen_or_IndPtr is a null pointer, no length or indicator value is used. This is an error when fetching data and the data is NULL.
See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用ODBC API进行数据库查询时,可以使用`SQLFetch`函数来从结果集中检索一行数据。要存储检索到的数据,可以使用结构体来定义数据的存储格式。以下是一个示例代码,展示了如何使用结构体存储从结果集中检索到的数据: ```cpp #include <iostream> #include <sql.h> #include <sqlext.h> struct Employee { SQLINTEGER id; SQLCHAR name[256]; SQLINTEGER age; }; void FetchData(SQLHSTMT stmt) { SQLRETURN ret; Employee employee; while ((ret = SQLFetch(stmt)) == SQL_SUCCESS) { SQLGetData(stmt, 1, SQL_C_SLONG, &employee.id, sizeof(employee.id), NULL); SQLGetData(stmt, 2, SQL_C_CHAR, employee.name, sizeof(employee.name), NULL); SQLGetData(stmt, 3, SQL_C_SLONG, &employee.age, sizeof(employee.age), NULL); // 在这里可以对 employee 进行处理,比如打印或存储数据 std::cout << "ID: " << employee.id << std::endl; std::cout << "Name: " << employee.name << std::endl; std::cout << "Age: " << employee.age << std::endl; std::cout << std::endl; } if (ret == SQL_ERROR) { // 获取数据出错,可以调用 SQLGetDiagRec 获取错误信息 } } int main() { SQLHENV env; SQLHDBC conn; SQLHSTMT stmt; SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0); SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); SQLCHAR connStrOutput[256]; SQLSMALLINT connStrOutputSize; SQLDriverConnect(conn, NULL, (SQLCHAR*)"DRIVER={SQL Server};SERVER=localhost;DATABASE=mydatabase;UID=myusername;PWD=mypassword", SQL_NTS, connStrOutput, sizeof(connStrOutput), &connStrOutputSize, SQL_DRIVER_COMPLETE); SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); SQLExecDirect(stmt, (SQLCHAR*)"SELECT id, name, age FROM employees", SQL_NTS); FetchData(stmt); SQLFreeHandle(SQL_HANDLE_STMT, stmt); SQLDisconnect(conn); SQLFreeHandle(SQL_HANDLE_DBC, conn); SQLFreeHandle(SQL_HANDLE_ENV, env); return 0; } ``` 在这个示例代码中,定义了一个名为`Employee`的结构体,用于存储从结果集中检索到的员工数据使用`SQLGetData`函数将每列数据存储到结构体的成员变量中,然后可以对结构体进行后续处理,比如打印或存储数据。注意,`SQLGetData`函数的第二个参数指定了要检索的列的索引,第三个参数指定了要将数据转换为的C数据类型,第四个参数是接收数据的缓冲区,最后一个参数是缓冲区大小。 这个示例代码连接到数据库,执行了一个查询语句,并使用`FetchData`函数从结果集中逐行检索数据,并将其存储到`Employee`结构体中进行处理。你可以根据自己的需求修改代码并定义适合自己数据类型的结构体来存储检索到的数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值