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

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

1. 基于SQLBindCol 函数

2. 基于SQLGetData 函数

3. SQLBindCol 和 SQLGetData 函数结合。

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

目录

1. 参数简介

2. 代码示例:

2.1 示例

2.2 结果:

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

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

1. 函数及参数简介

        应用程序不使用SQLBindCol将结果集列绑定到程序变量。每次调用SQLFetch之后,应用程序都会为结果集中的每一列调用SQLGetData一次。SQLGetData指示驱动程序将数据从特定的结果集列转移到特定的程序变量,并指定列和变量的数据类型。这允许驱动程序在结果列和程序变量具有不同的数据类型时转换数据。Text、ntext和image列通常太大,无法放入程序变量,但仍然可以使用SQLGetData检索。如果结果列中的文本、ntext或图像数据大于程序变量,SQLGetData将返回SQL_SUCCESS_WITH_INFO和SQLSTATE 01004(右截短的字符串数据)。对SQLGetData的连续调用将返回连续的文本或图像数据块。

        简单来说使用 SQLGetData 时,每调用一次 SQLFetch函数获取的结果集,就调用 SQLGetData 获取指定列的值。

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

简单的来说:

参数1:操作的句柄。

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

参数3:该列的数据类型

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

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

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

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

2. 代码示例:

2.1 示例

SQLCHAR t1[32], t2[255], t3[255];
SQLLEN Strlen_or_IndPtr = 0;    
for (int i = 0;; i++)
    {
        res = SQLFetch(myStatementHandle);     //获取结果集
        res = SQLGetData(myStatementHandle, 1, SQL_C_DEFAULT, &t1, 32, &Strlen_or_IndPtr);       //  获取结果集中列数据
        res = SQLGetData(myStatementHandle, 2, SQL_C_DEFAULT, &t2, 255, &Strlen_or_IndPtr);
        res = SQLGetData(myStatementHandle, 3, SQL_C_DEFAULT, &t3, 255, &Strlen_or_IndPtr);
        
        if (res == SQL_ERROR || res == SQL_SUCCESS_WITH_INFO)
            break;
        if (res == SQL_SUCCESS || res == SQL_SUCCESS_WITH_INFO)
        {
            cout << i + 1 << " -- " << t1 <<" -- " << t2 << " -- " << t3 << " -- " << Strlen_or_IndPtr << endl;
        }
        else
        {
            cout << res;
            break;
        }
    }

【释】:

t1[32], t2[255], t3[255] 变量和数据表的列对应。如下图:

数据表

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

res = SQLGetData(myStatementHandle, 1, SQL_C_DEFAULT, &t1, 32, &Strlen_or_IndPtr);

 myStatementHandle:为句柄;

1:代表第 1 列;

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

t1:保存结果变量;

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. SQLGetData 函数参数详细说明

摘自MSDN。

(1)StatementHandle

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

(2)ColumnNumber

[Input] Number of the column for which to return data. Result set columns are numbered in increasing column order starting at 1. The bookmark column is column number 0; this can be specified only if bookmarks are enabled.
【释义】
要为其返回数据的列的编号。结果集列从1开始按列顺序递增编号。书签列为列号0;只有启用了书签,才能指定此参数。

(3)TargetType

[Input] The type identifier of the C data type of the * TargetValuePtr buffer. For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types. If TargetType is SQL_ARD_TYPE, the driver uses the type identifier specified in the SQL_DESC_CONCISE_TYPE field of the ARD. If it is SQL_C_DEFAULT, the driver selects the default C data type based on the SQL data type of the source.
【释义】
*TargetValuePtr缓冲区的C数据类型的类型标识符。有关有效的C数据类型和类型标识符的列表,请参见附录D:数据类型中的C数据类型部分。如果TargetType为SQL_ARD_TYPE,驱动使用ARD的SQL_DESC_CONCISE_TYPE字段中指定的类型标识符。如果是SQL_C_DEFAULT,驱动程序将根据源的SQL数据类型选择默认的C数据类型。

(4)TargetValuePtr

[Output] Pointer to the buffer in which to return the data.
【释义】
指向在其中返回数据的缓冲区的指针

(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 returning variable-length data, such as character or binary data. Note that the driver counts the null-termination character when returning 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. It is therefore 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.
SQLGetData returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength is 0.
【释义】
驱动程序使用BufferLength来避免在返回变长数据(如字符或二进制数据)时写入超过*TargetValuePtr缓冲区的末尾。注意,当返回字符数据到*TargetValuePtr时,驱动程序计数空终止字符。因此TargetValuePtr必须包含空终止字符的空间,否则驱动程序将截断数据。
当驱动程序返回固定长度的数据时,例如一个整数或一个日期结构,驱动程序忽略BufferLength并假设缓冲区足够大以容纳数据。因此,对于应用程序来说,为固定长度的数据分配一个足够大的缓冲区是很重要的,否则驱动程序将写入超过缓冲区末端的数据。
当BufferLength小于0时返回SQLSTATE HY090(无效字符串或缓冲区长度),而当BufferLength为0时则不返回SQLSTATE HY090。

(6)StrLen_or_IndPtr

[Output] Pointer to the buffer in which to return the length or indicator value. If this is a null pointer, no length or indicator value is returned. This returns an error when the data being fetched is NULL.
【释义】
指向缓冲区的指针,在其中返回长度或指示值。如果这是一个空指针,则不返回长度或指示值。当获取的数据为NULL时,将返回一个错误
SQLGetData can return the following values in the length/indicator buffer:
  • The length of the data available to return
  • SQL_NO_TOTAL
  • SQL_NULL_DATA
For more information, see Using Length/Indicator Values and "Comments" in this topic.
好的,我可以给你讲一下使用ODBC函数封装MySQL数据库的方法。 1. 安装和配置MySQL ODBC驱动程序和ODBC数据源。你需要先到MySQL官网上下载和安装MySQL ODBC驱动程序,然后在ODBC数据源管理器中配置好ODBC数据源,包括设置数据源名称、服务器地址、端口号、数据库名称、用户名和密码等。 2. 在代码中使用ODBC API连接到MySQL数据库。你可以使用以下代码连接到MySQL数据库: ```c++ #include <windows.h> #include <sql.h> #include <sqlext.h> SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN retcode; SQLCHAR *dsn = (SQLCHAR*)"your_dsn_name"; SQLCHAR *uid = (SQLCHAR*)"your_username"; SQLCHAR *pwd = (SQLCHAR*)"your_password"; retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER); retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); retcode = SQLConnect(hdbc, dsn, SQL_NTS, uid, SQL_NTS, pwd, SQL_NTS); ``` 3. 执行SQL语句。你可以使用以下代码执行SQL语句: ```c++ SQLCHAR *sql = (SQLCHAR*)"select * from your_table"; retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); retcode = SQLExecDirect(hstmt, sql, SQL_NTS); ``` 4. 处理查询结果。你可以使用以下代码处理查询结果: ```c++ SQLCHAR name[256]; SQLINTEGER age; while (SQLFetch(hstmt) == SQL_SUCCESS) { SQLGetData(hstmt, 1, SQL_C_CHAR, name, 256, NULL); SQLGetData(hstmt, 2, SQL_C_LONG, &age, 0, NULL); printf("Name: %s, Age: %d\n", name, age); } ``` 5. 断开与MySQL数据库的连接。你可以使用以下代码断开与MySQL数据库的连接: ```c++ retcode = SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); ``` 需要注意的是,在使用ODBC函数封装MySQL数据库的过程中,你需要熟悉ODBC函数的使用方法和MySQL数据库的相关知识。此外,你需要注意代码的安全性和可靠性,例如防止SQL注入等问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值