一致性
引入的版本:ODBC 1.0 标准符合性:ISO 92
总结
SQLBindCol 将应用数据缓冲区绑定到结果集中的列。
Syntax
SQLRETURN SQLBindCol(
SQLHSTMT StatementHandle,
SQLUSMALLINT ColumnNumber,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
Arguments
StatementHandle
[输入]语句句柄。
列号
[输入]结果集的列数要绑定。 列号按列序递增排列,从0开始,列0为书签列。 如果不使用书签——即SQL_ATTR_USE_BOOKMARKS语句属性设置为SQL_UB_OFF——则列号从1开始。
目标类型
[输入]*TargetValuePtr 缓冲区的C数据类型标识符。 当它用 SQLFetch、 SQLFetchScroll、 SQLBulkOperations 或 SQLSetPos 从数据源检索数据时,驱动会将数据转换成这种类型;当它通过 SQLBulkOperations 或 SQLSetPos 向数据源发送数据时,驱动程序会将该类型的数据转换。 有关有效C型数据类型和类型标识符的列表,请参见附录D:数据类型中的 C型别 部分。
如果 TargetType 参数是区间数据类型,则数据使用默认的区间前导精度(2)和默认区间秒精度(6),分别在 ARD 的SQL_DESC_DATETIME_INTERVAL_PRECISION和SQL_DESC_PRECISION字段中设置。 如果 TargetType 参数被SQL_C_NUMERIC,则使用默认精度(驱动程序定义)和默认刻度(0),这些参数在 ARD 的 SQL_DESC_PRECISION 和 SQL_DESC_SCALE 字段中设置。 如果任何默认精度或缩放不合适,应用程序应通过调用 SQLSetDescField 或 SQLSetDescRec 显式设置相应的描述符字段。
还可以指定扩展的 C 数据类型。 有关详细信息,请参阅 ODBC 中的 C 数据类型。
目标值Ptr
[延迟输入/输出]指向数据缓冲区绑定到列。
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 参数是有效值。
BufferLength
[输入]*TargetValuePtr 缓冲区的长度(字节单位)。
驱动程序使用 BufferLength 以避免在返回可变长度数据(如字符或二进制数据)时写入超过*TargetValuePtr 缓冲区的末尾。 注意,驱动程序在返回字符数据到 *TargetValuePtr 时,计数了空终止字符。 *因此,TargetValuePtr必须包含空终止字符的空间,否则驱动会截断数据。
当驱动程序返回固定长度的数据,如整数或日期结构时,忽略 缓冲区 长度,并假设缓冲区足够大以容纳数据。 因此,应用程序必须为固定长度数据分配足够大的缓冲区,否则驱动程序会写入缓冲区末端之后。
当 BufferLength 小于 0 时,SQLBindCol 返回 SQLSTATE HY090(字符串或缓冲区长度无效),但当 BufferLength 为 0 时则不返回。 然而,如果 TargetType 指定了字符类型,应用程序不应将 BufferLength 设为 0,因为符合 ISO CLI 标准的驱动程序在此情况下返回 SQLSTATE HY090(无效字符串或缓冲区长度)。
StrLen_or_IndPtr
[延迟输入/输出]指向长度/指示缓冲区,绑定到列。
SQLFetch 和 SQLFetchScroll 会在这个缓冲区返回一个值。 当操作为SQL_ADD、SQL_UPDATE_BY_BOOKMARK或SQL_DELETE_BY_BOOKMARK时,SQLBulkOperations 会从该缓冲区获取一个值。
当操作SQL_FETCH_BY_BOOKMARK时,SQLBulkOperations 会返回该缓冲区中的一个值。
当操作SQL_REFRESH时,SQLSetPos 会返回该缓冲区中的一个值;当操作被SQL_UPDATE时,它会从该缓冲区获取一个值。
SQLFetch、 SQLFetchScroll、 SQLBulkOperations 和 SQLSetPos 可以在长度/指示缓冲区返回以下值:
可返回的数据长度
SQL_NO_TOTAL
SQL_NULL_DATA
应用程序可以在长度/指示缓冲区中输入以下值,用于 SQLBulkOperations 或 SQLSetPos:
发送数据的长度
SQL_NTS
SQL_NULL_DATA
SQL_DATA_AT_EXEC
SQL_LEN_DATA_AT_EXEC宏的结果
SQL_COLUMN_IGNORE
如果指示缓冲区和长度缓冲区是独立缓冲区,指示缓冲区只能返回SQL_NULL_DATA,而长度缓冲区可以返回所有其他值。
更多信息请参见 SQLBulkOperations 函数、 SQLFetch 函数、 SQLSetPos 函数以及 使用 长度/指示值。
如果 StrLen_or_IndPtr 是空指针,则不使用长度或指示值。 这是在获取数据时出现的错误,且数据为NULL。
如果应用程序将在 64 位操作系统上运行,请参阅 ODBC 64 位信息。
Returns
SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR 或SQL_INVALID_HANDLE。
诊断
当 SQLBindCol 返回 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO 时,可以通过调用 SQLGetDiagRec 获得关联的 SQLSTATE 值,Handle 为 SQL_HANDLE_STMT,Handle 为 StatementHandle。 下表列出了 SQLBindCol 通常返回的SQLSTATE值,并在此函数的上下文中解释了每个值;“(DM)” 符号位于驱动程序管理器返回的 SQLSTATE 描述之前。 除非另有说明,否则与每个 SQLSTATE 值关联的返回代码SQL_ERROR。
| SQLSTATE | Error | Description |
|---|---|---|
| 01000 | 常规警告 | 特定于驱动程序的信息性消息。 (函数返回SQL_SUCCESS_WITH_INFO。) |
| 07006 | 受限数据类型属性冲突 | (DM) ColumnNumber 参数为 0,TargetType 参数也没有 SQL_C_BOOKMARK 或 SQL_C_VARBOOKMARK。 |
| 07009 | 无效描述子索引 | 参数 ColumnNumber 的值超过了结果集中列数的最大值。 |
| HY000 | 常规错误 | 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 *MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。 |
| HY001 | 内存分配错误 | 驱动程序无法分配支持执行或完成函数所需的内存。 |
| HY003 | 应用程序缓冲区类型无效 | 参数 TargetType 既不是有效的数据类型,也不是SQL_C_DEFAULT。 |
| HY010 | 函数序列错误 | (DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 当调用 SQLBindCol 时,这个异步函数仍在执行。 (DM) 为 StatementHandle 调用了 SQLExecute、SQLExecDirect 或 SQLMoreResults,并返回了SQL_PARAM_DATA_AVAILABLE。 在检索所有流式处理参数的数据之前调用此函数。 (DM) 为 StatementHandle 调用异步执行函数,并在调用此函数时仍在执行。 (DM) 为 StatementHandle 调用了 SQLExecute、SQLExecDirect、SQLBulkOperations 或 SQLSetPos,并返回了SQL_NEED_DATA。 在为所有数据执行参数或列发送数据之前调用此函数。 |
| HY013 | 内存管理错误 | 无法处理函数调用,因为基础内存对象无法访问,可能是因为内存条件低。 |
| HY090 | 字符串或缓冲区长度无效 | (DM) 参数 BufferLength 指定的值小于 0。 (DM)司机是ODBC 2型。x 驱动程序中, ColumnNumber 参数设置为 0,参数 BufferLength 指定的值不等于 4。 |
| HY117 | 连接因未知事务状态而挂起。 仅允许断开连接和只读函数。 | (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数。 |
| HYC00 | 未实现可选功能 | 驱动程序或数据源不支持由 TargetType 参数与对应列驱动特定 SQL 类型组合所指定的转换。 参数 ColumnNumber 为 0,且驱动不支持书签。 该驱动程序仅支持 ODBC 2。x 和参数 TargetType 是以下之一: SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT 以及附录D中C数据 类型 中列出的任何区间C数据类型。 该驱动程序仅支持 3.50 之前的 ODBC 版本,参数 TargetType 被SQL_C_GUID。 |
| HYT01 | 超过连接超时时间 | 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_CONNECTION_TIMEOUT。 |
| IM001 | 驱动程序不支持此函数 | (DM) 与 StatementHandle 关联的驱动程序不支持该函数。 |
Comments
SQLBindCol 用于将结果集中的列关联或 绑定 到应用程序中的数据缓冲区和长度/指示缓冲区。 当应用程序调用 SQLFetch、 SQLFetchScroll 或 SQLSetPos 获取数据时,驱动程序返回指定缓冲区中绑定列的数据;更多信息请参见 SQLFetch 函数。 当应用程序调用 SQLBulkOperations 更新或插入行或 SQLSetPos 更新行时,驱动程序会从指定的缓冲区获取绑定列的数据;更多信息请参见 SQLBulkOperations 函数 或 SQLSetPos 函数。 有关绑定的更多信息,请参见检索 结果(基础)。
注意,列不必绑定即可检索数据。 应用程序还可以调用 SQLGetData 从列中获取数据。 虽然可以绑定行中的某些列并调用其他列的 SQLGetData ,但这会受到一些限制。 更多信息请参见 SQLGetData。
装订、解订和重新装订列
列可以随时被绑定、解绑定或重新绑定,即使数据已经从结果集中取出。 新的绑定将在下一次调用使用绑定的函数时生效。 例如,假设一个应用程序绑定结果集中的列并调用 SQLFetch。 驱动程序返回绑定缓冲区中的数据。 现在假设应用程序将列绑定到另一组缓冲区。 驱动程序不会将刚取出的行数据放入新绑定的缓冲区。 相反,它会等到再次调用 SQLFetch 后,将下一行的数据放入新绑定的缓冲区。
注释
在将列绑定到列0之前,语句属性SQL_ATTR_USE_BOOKMARKS应始终设置。 这不是必须的,但强烈建议。
绑定列
绑定列时,应用程序调用 SQLBindCol ,传递数据缓冲区的列号、类型、地址和长度,以及长度/指示缓冲区的地址。 有关这些地址的使用方式,请参见本节后面的“缓冲区地址”。 有关绑定列的更多信息,请参见 使用 SQLBindCol。
这些缓冲区的使用被推迟;也就是说,应用程序在 SQLBindCol 中绑定它们,但驱动程序通过其他函数访问它们——即 SQLBulkOperations、SQLFetch、SQLFetchScroll 或 SQLSetPos。 应用程序有责任确保只要绑定有效, SQLBindCol 中指定的指针始终有效。 如果应用程序允许这些指针失效——例如释放缓冲区——然后调用一个期望它们有效的函数,后果则未定义。 更多信息请参见 延期缓冲区。
该绑定一直有效,直到被新的绑定取代、列被解除绑定,或语句被释放。
解订柱
要解绑单一列,应用程序调用 SQLBindCol,ColumnNumber 设置为该列号,TargetValuePtr 设置为空指针。 如果 ColumnNumber 指的是未绑定的列, SQLBindCol 仍然返回SQL_SUCCESS。
要解绑所有列,应用程序调用 SQLFreeStmt,fOption 设为 SQL_UNBIND。 这也可以通过将ARD的场SQL_DESC_COUNT设为零来实现。
重新装订柱
应用程序可以执行两个操作之一来更改绑定:
调用 SQLBindCol 为已经绑定的列指定新的绑定。 驱动程序使用新绑定覆盖旧绑定。
指定一个偏移量添加到由绑定调用 SQLBindCol 指定的缓冲区地址上。 更多信息请参见下一节“装订偏移”。
绑定偏移量
绑定偏移量是在数据和长度/指示缓冲区的地址(如 TargetValuePtr 和 StrLen_or_IndPtr 参数中指定)被添加的值,然后才被取消引用。 当使用偏移时,绑定是应用程序缓冲区布局的“模板”,应用程序可以通过改变偏移量将该“模板”移动到内存的不同区域。 由于每个绑定中每个地址都添加了相同的偏移量,不同列缓冲区之间的相对偏移必须在每个缓冲区组内保持一致。 当采用行数装订时,这一点总是成立;应用必须仔细布局缓冲区,才能在使用列级绑定时实现这一点。
使用绑定偏移量的效果基本上和调用 SQLBindCol重新绑定列一样。 区别在于,调用 SQLBindCol 会指定数据缓冲区和长度/指示缓冲区的新地址,而使用绑定偏移量不会改变地址,只是增加一个偏移量。 应用程序可以随时指定新的偏移量,且该偏移量总是添加到最初绑定的地址上。 特别地,如果偏移量设置为0或语句属性设置为空指针,驱动程序使用最初绑定的地址。
为了指定绑定偏移量,应用程序将SQL_ATTR_ROW_BIND_OFFSET_PTR语句属性设置为SQLINTEGER 缓冲区的地址。 在应用程序调用使用绑定的函数之前,会在缓冲区中放入一个以字节为单位的偏移量。 为了确定缓冲区的地址,驱动程序将偏移量加到绑定中的地址上。 地址和偏移量的和必须是有效地址,但偏移量添加的地址不必有效。 关于绑定偏移的使用方式,请参见本节后面的“缓冲区地址”。
绑定数组
如果行集大小(SQL_ATTR_ROW_ARRAY_SIZE语句属性的值)大于1,应用程序绑定的是缓冲区数组而非单个缓冲区。 更多信息请参见 “阻挡光标”。
应用程序可以通过两种方式绑定数组:
将数组绑定到每个列。 这被称为 列绑定 ,因为每个数据结构(数组)都包含单个列的数据。
定义一个结构来存储整行的数据,并绑定这些结构的数组。 这被称为 逐行绑定 ,因为每个数据结构都包含单一行的数据。
每个缓冲区数组的元素数量必须至少等于行集的大小。
注释
应用程序必须验证对齐的有效性。 有关阵营考虑的更多信息,请参见 阵营。
按列绑定
在逐列绑定中,应用程序为每一列绑定独立的数据数组和长度/指示符数组。
要使用列绑定,应用程序首先将SQL_ATTR_ROW_BIND_TYPE语句属性设置为SQL_BIND_BY_COLUMN。 (这是默认值。对于要绑定的每个列,应用程序将执行以下步骤:
分配一个数据缓冲数组。
分配长度/指示器缓冲区数组。
注释
如果使用列式绑定时,应用程序直接写入描述符,则可以将单独的数组用于长度和指示器数据。
调用 SQLBindCol 并使用以下参数:
TargetType 是数据缓冲数组中单个元素的类型。
TargetValuePtr 是数据缓冲数组的地址。
缓冲长度 是数据缓冲数组中单个元素的大小。 当数据是固定长度的数据时,将忽略 BufferLength 参数。
StrLen_or_IndPtr 是长度/指示器数组的地址。
有关该信息如何使用的更多信息,请参见本节后面的“缓冲区地址”。 关于按列装订的更多信息,请参见 BindingColumn-Wise。
按行绑定
在按行绑定中,应用程序定义一个结构,包含每个待绑定列的数据缓冲区和长度/指示符缓冲区。
若要使用按行绑定,应用程序将执行以下步骤:
定义一个结构以存储单行数据(包括数据和长度/指示缓冲区),并分配这些结构的数组。
注释
如果使用行绑定时应用程序直接写入描述符,则可以将单独的字段用于长度和指示器数据。
将SQL_ATTR_ROW_BIND_TYPE语句属性设置为包含单行数据的结构大小,或将结果列绑定到缓冲区实例的大小。 长度必须包含所有绑定列的空间,以及结构或缓冲区的任何填充,以确保当绑定列的地址按指定长度递增时,结果会指向下一行同一列的起点。 在 ANSI C 中使用 sizeof 运算符时,可以保证此行为。
调用 SQLBindCol ,每个列的绑定参数如下:
TargetType 是要绑定到该列的数据缓冲区成员类型。
TargetValuePtr 是第一个数组元素中数据缓冲区成员的地址。
缓冲长度 是数据缓冲区成员的大小。
StrLen_or_IndPtr 是要绑定的长度/指示器成员的地址。
有关该信息如何使用的更多信息,请参见本节后面的“缓冲区地址”。 关于按列装订的更多信息,请参见 BindingRow-Wise。
缓冲区地址
缓冲区地址是数据或长度/指示缓冲区的实际地址。 驱动程序在写入缓冲区之前(例如取指时)计算缓冲区地址。 它由以下公式计算,该公式使用了 TargetValuePtr 和 StrLen_or_IndPtr 参数中指定的地址、绑定偏移量和行号:
绑定地址 + 绑定偏移 量 + ((行号 - 1) x 元素大小)
其中公式的变量定义如下表所述。
| Variable | Description |
|---|---|
| 绑定地址 | 对于数据缓冲区,地址是 SQLBindCol 中用 TargetValuePtr 参数指定的。 对于长度/指示缓冲区,地址是 SQLBindCol 中用 StrLen_or_IndPtr 参数指定的。 更多信息请参见“描述符和 SQLBindCol” 部分的“附加注释”。 如果绑定地址为0,则不会返回任何数据值,即使前述公式计算的地址非零。 |
| 绑定偏移 | 如果使用行绑定,则存储在带有SQL_ATTR_ROW_BIND_OFFSET_PTR语句属性的地址上的值。 如果使用列绑定,或者SQL_ATTR_ROW_BIND_OFFSET_PTR语句属性的值是空指针,绑 定偏移 量为0。 |
| 行号 | 行集中行的基于1的数字。 对于默认的单行取用,这个数值为1。 |
| 元素大小 | 绑定数组中元素的大小。 如果使用列绑定,长度/指示符缓冲区的大小( SQLINTEGER) 为单位。 对于数据缓冲区,如果数据类型是可变长度,则为 SQLBindCol 中 BufferLength 参数的值;如果数据类型是固定长度,则为数据类型的大小。 如果采用行绑定,则该值为数据和长度/指示缓冲区的SQL_ATTR_ROW_BIND_TYPE语句属性值。 |
描述符与 SQLBindCol
以下章节将描述 SQLBindCol 如何与描述符交互。
Caution
调用 SQLBindCol 对一个语句可能影响其他语句。 当显式分配与该语句关联的 ARD 并且也与其他语句关联时,将发生这种情况。 由于 SQLBindCol 修改描述符,修改适用于所有关联该描述符的语句。 如果这不是要求的行为,应用程序应在调用 SQLBindCol 前将该描述符与其他语句分离。
参数映射
从概念上讲, SQLBindCol 依次执行以下步骤:
调用 SQLGetStmtAttr 以获取 ARD 句柄。
调用 SQLGetDescField 获取该描述符的SQL_DESC_COUNT字段,如果 ColumnNumber 参数中的值超过 SQL_DESC_COUNT,则调用 SQLSetDescField 将 SQL_DESC_COUNT 的值提高到 ColumnNumber。
多次调用 SQLSetDescField ,为ARD的以下字段分配值:
将 SQL_DESC_TYPE 和 SQL_DESC_CONCISE_TYPE 设置为 TargetType 的值,但如果 TargetType 是日期时间或区间子类型的简明标识符之一,则分别将 SQL_DESC_TYPE 设置为 SQL_DATETIME 或 SQL_INTERVAL;将SQL_DESC_CONCISE_TYPE设置为简明标识符;并将SQL_DESC_DATETIME_INTERVAL_CODE设置为对应的日期时间或区间子码。
根据 TargetType 设置 SQL_DESC_LENGTH、SQL_DESC_PRECISION、SQL_DESC_SCALE 和 SQL_DESC_DATETIME_INTERVAL_PRECISION 中的一个或多个。
将SQL_DESC_OCTET_LENGTH字段设置为 BufferLength 的值。
将SQL_DESC_DATA_PTR字段设置为 TargetValuePtr。
将SQL_DESC_INDICATOR_PTR场设为 StrLen_or_IndPtr值。 (详见下一段。)
将SQL_DESC_OCTET_LENGTH_PTR字段设置为 StrLen_or_IndPtr。 (详见下一段。)
StrLen_or_IndPtr参数所指变量既用于指示信息,也用于长度信息。 如果取指在该列遇到空值,它会将SQL_NULL_DATA存储在这个变量中;否则,它会将数据长度存储在这个变量中。 将空指针传递为 StrLen_or_IndPtr 可以防止取指针返回数据长度,但如果遇到空值且无法返回SQL_NULL_DATA,取指针会失败。
如果调用 SQLBindCol 失败,ARD 中本应设置的描述符字段内容未定义,ARD SQL_DESC_COUNT字段的值保持不变。
COUNT字段的隐式重置
SQLBindCol 只有在 ColumnNumber 参数会增加 SQL_DESC_COUNT 值时,才将 SQL_DESC_COUNT 设置为 ColumnNumber 参数的值。 如果 TargetValuePtr 参数中的值是空指针,且 ColumnNumber 参数中的值等于 SQL_DESC_COUNT(即解绑最大束缚列时),则 SQL_DESC_COUNT 设置为剩余最大束缚列的编号。
关于SQL_DEFAULT的注意事项
为了成功检索列数据,应用程序必须正确确定应用缓冲区中数据的长度和起始点。 当应用程序指定显式 目标类型时,应用误解很容易被发现。 然而,当应用程序指定SQL_DEFAULT的 目标类型 时, SQLBindCol 可以应用于与应用程序预期数据类型的不同列,无论是通过元数据的更改,还是将代码应用到不同的列。 在这种情况下,应用程序可能并不总是确定被取列数据的起始或长度。 这可能导致未报告的数据错误或内存违规。
代码示例
在以下示例中,应用程序在客户表上执行 SELECT 语句,返回按姓名排序的客户ID、姓名和电话号码的结果集。 然后调用 SQLBindCol 将数据列绑定到本地缓冲区。 最后,应用程序用 SQLFetch 获取每行数据,并打印每位客户的姓名、ID 和电话号码。
更多代码示例请参见 SQLBulkOperations 函数、 SQLColumns 函数、 SQLFetchScroll 函数和 SQLSetPos 函数。
// SQLBindCol_ref.cpp
// compile with: odbc32.lib
#include <windows.h>
#include <stdio.h>
#define UNICODE
#include <sqlext.h>
#define NAME_LEN 50
#define PHONE_LEN 60
void show_error() {
printf("error\n");
}
int main() {
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt = 0;
SQLRETURN retcode;
SQLWCHAR szName[NAME_LEN], szPhone[PHONE_LEN], sCustID[NAME_LEN];
SQLLEN cbName = 0, cbCustID = 0, cbPhone = 0;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Connect to data source
retcode = SQLConnect(hdbc, (SQLWCHAR*) L"NorthWind", SQL_NTS, (SQLWCHAR*) NULL, 0, NULL, 0);
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
retcode = SQLExecDirect(hstmt, (SQLWCHAR *) L"SELECT CustomerID, ContactName, Phone FROM CUSTOMERS ORDER BY 2, 1, 3", SQL_NTS);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
// Bind columns 1, 2, and 3
retcode = SQLBindCol(hstmt, 1, SQL_C_WCHAR, &sCustID, 100, &cbCustID);
retcode = SQLBindCol(hstmt, 2, SQL_C_WCHAR, szName, NAME_LEN, &cbName);
retcode = SQLBindCol(hstmt, 3, SQL_C_WCHAR, szPhone, PHONE_LEN, &cbPhone);
// Fetch and print each row of data. On an error, display a message and exit.
for (int i=0 ; ; i++) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)
show_error();
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
//replace wprintf with printf
//%S with %ls
//warning C4477: 'wprintf' : format string '%S' requires an argument of type 'char *'
//but variadic argument 2 has type 'SQLWCHAR *'
//wprintf(L"%d: %S %S %S\n", i + 1, sCustID, szName, szPhone);
printf("%d: %ls %ls %ls\n", i + 1, sCustID, szName, szPhone);
}
else
break;
}
}
// Process data
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLCancel(hstmt);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
}
SQLDisconnect(hdbc);
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
}
另见 ODBC项目示例。
相关函数
| 有关以下内容的信息 | 请参阅 |
|---|---|
| 返回有关结果集中的列的信息 | SQLDescribeCol函数 |
| 提取数据块或滚动结果集 | SQLFetchScroll 函数 |
| 提取多行数据 | SQLFetch 函数 |
| 在语句上释放列缓冲区 | SQLFreeStmt 函数 |
| 提取部分或全部数据列 | SQLGetData 函数 |
| 返回结果集列数 | SQLNumResultCols 函数 |