SQLBindCol 函数 (CLI)-将列绑定到应用程序变量或 LOB 定位器

应用程序可以将结果集中的列与 C 数据类型变量相关联 (绑定) ,并将结果集中的 LOB 列与 LOB 定位器相关联 (绑定)。

规范:

  • CLI 1.1
  • ODBC 1.0
  • ISO CLI
SQLBindCol() 用于将结果集中的列与以下任一项相关联:
  • 所有 C 数据类型的应用程序变量或应用程序变量数组 (存储器缓冲区)。 当调用 SQLFetch()SQLFetchScroll() 时,会将数据从 DBMS 传输到应用程序。 在传输数据时,可能会发生数据转换。
  • LOB 列的 LOB 定位器。 当调用 SQLFetch() 时,会将 LOB 定位器 (而不是数据本身) 从 DBMS 传输到应用程序。

    或者,可以使用 SQLBindFileToCol()将 LOB 列直接绑定到文件。

对于应用程序需要检索的结果集中的每个列,将调用一次 SQLBindCol()

通常,在此函数之前调用 SQLPrepare()SQLExecDirect() 或其中一个模式函数,然后调用 SQLFetch()SQLFetchScroll()SQLBulkOperations()SQLSetPos() 。 在调用 SQLBindCol()之前,可能还需要列属性,并且可以使用 SQLDescribeCol()SQLColAttribute()获取列属性。

语法

SQLRETURN   SQLBindCol (
               SQLHSTMT          StatementHandle,            /* hstmt */
               SQLUSMALLINT      ColumnNumber,               /* icol */
               SQLSMALLINT       TargetType,                 /* fCType */
               SQLPOINTER        TargetValuePtr,             /* rgbValue */
               SQLLEN            BufferLength,               /* cbValueMax */
               SQLLEN            *StrLen_or_IndPtr);         /* *pcbValue */

函数参数

表 1. SQLBindCol 自变量
数据类型 自变量 使用 描述
SQLHSTMT StatementHandle 输入 语句句柄
SQLUSMALLINT ColumnNumber 输入 标识列的编号。 从左到右按顺序对列进行编号。
  • 如果未使用书签,那么列号从 1 开始 (SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_OFF)。
  • 如果使用书签,那么列号从 0 开始 (语句属性设置为 SQL_UB_ON)。 列 0 是书签列。
SQLSMALLINT TargetType 输入 结果集中列号 ColumnNumber 的 C 数据类型。 当应用程序从数据源检索数据时,它会将数据转换为此 C 类型。 使用 SQLBulkOperations()SQLSetPos()时,驱动程序将在向数据源发送信息时转换此 C 数据类型的数据。 支持以下类型:
  • SQL_C_BINARY
  • SQL_C_BIT
  • SQL_C_BLOB_LOCATOR
  • SQL_C_CHAR
  • SQL_C_CLOB_LOCATOR
  • SQL_C_DBCHAR
  • SQL_C_DBCLOB_LOCATOR
  • SQL_C_DECIMAL_IBM
  • SQL_C_DOUBLE
  • SQL_C_FLOAT
  • SQL_C_LONG
  • SQL_C_NUMERIC a
  • SQL_C_SBIGINT
  • SQL_C_SHORT
  • SQL_C_TYPE_DATE
  • SQL_C_TYPE_TIME
  • SQL_C_TYPE_TIMESTAMP
  • SQL_C_TYPE_TIMESTAMP_EXT
  • SQL_C_TINYINT
  • SQL_C_UBIGINT
  • SQL_C_UTINYINT
  • SQL_C_WCHAR

指定 SQL_C_DEFAULT 会导致将数据传输到其缺省 C 数据类型。

SQLPOINTER TargetValuePtr 输入/输出 (延迟) 指向缓冲区或具有按列或按行绑定的缓冲区数组的指针,其中 CLI 用于在发生访存时存储列数据或 LOB 定位器。

此缓冲区用于在调用以下任何函数时返回数据: SQLFetch()SQLFetchScroll()SQLSetPos() (使用 操作 自变量 SQL_REFRESH) 或 SQLBulkOperations() (使用 操作 自变量SQL_FETCH_BY_书签)。

否则, SQLBulkOperations()SQLSetPos() 使用缓冲区来检索数据。

如果 TargetValuePtr 为空,则该列未绑定。 可以通过使用 SQL_UNBIND 选项调用 SQLFreeStmt() 来取消所有列的绑定。

SQLLEN BufferLength 输入 可用于存储列数据或LOB定位 TargetValuePtr 缓冲区的大小(以字节为单位)。

如果 TargetType 表示二进制或字符串 (单字节或双字节) ,或者对于返回可变长度数据的列是 SQL_C_DEFAULT ,那么 BufferLength 必须> 0 ,否则将返回错误。 请注意,对于字符数据,驱动程序会计算 NULL 终止字符,因此必须为其分配空间。 对于所有其他数据类型,将忽略此参数。

SQLLEN * StrLen_or_IndPtr 输入/输出 (延迟) 指向值的指针(或值数组),指示 CLI TargetValuePtr中可返回的字节数。 如果 TargetType 是 LOB 定位器,那么将返回定位器的大小,而不是 LOB 数据的大小。

此缓冲区用于在调用以下任何函数时返回数据: SQLFetch()SQLFetchScroll()SQLSetPos() (使用 操作 自变量 SQL_REFRESH) 或 SQLBulkOperations() (使用 操作 自变量SQL_FETCH_BY_书签)。

否则, SQLBulkOperations()SQLSetPos() 使用缓冲区来检索数据。

如果列的数据值为空,那么 SQLFetch() 将在此自变量中返回 SQL_NULL_DATA。

对于每个绑定列,此指针值必须是唯一的,或者为 NULL。 可以设置值 SQL_COLUMN_IGNORE , SQL_NTS , SQL_NULL_DATA 或数据长度以用于 SQLBulkOperations()

也可能返回 SQL_NO_LENGTH ,请参阅 "用法" 部分以获取更多信息。

  • 对于此函数, TargetValuePtrStrLen_or_IndPtr 都是延迟输出,这意味着这些指针指向的存储位置在获取结果集行之前不会更新。 因此,这些指针引用的位置必须保持有效,直到调用 SQLFetch()SQLFetchScroll() 为止。 例如,如果 SQLBindCol() 在局部函数中被调用,则 SQLFetch() 必须在同一函数范围内被调用,或者 TargetValuePtr必须被分配为静态或全局。
  • 如果将 TargetValuePtr 连续放置在 StrLen_or_IndPtr 之后的内存中, CLI 将能够优化所有可变长度数据类型的数据检索。

用法

对结果集中要检索其数据或 LOB 列的 LOB 定位器的每个列调用一次 SQLBindCol() 。 当 SQLFetch()SQLFetchScroll() 被调用从结果集中检索数据时,每个绑定列中的数据被放置在 TargetValuePtrStrLen_or_IndPtr指定的位置。 当语句属性 SQL_ATTR_ROW_ARRAY_SIZE 大于 1 时, TargetType 应该引用缓冲区数组。 如果 TargetType 是 LOB 定位器,那么将返回定位器值,而不是返回实际 LOB 数据。 LOB 定位器引用 LOB 列中的整个数据值。

如果 CLI 应用程序未使用函数 SQLBindCol() 为 LOB 列提供输出缓冲区,那么缺省情况下, IBM® 数据服务器客户机 将代表应用程序为结果集中的每个 LOB 列请求 LOB 定位器。

列由从左到右按顺序分配的数字标识。
  • 如果未使用书签,那么列号从 1 开始 (SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_OFF)。
  • 如果使用书签 (语句属性设置为 SQL_UB_ON) ,那么列号从 0 开始。

在绑定列之后,在后续访存中,应用程序可以通过调用 SQLBindCol()来更改这些列的绑定或绑定先前未绑定的列。 新绑定不适用于已访存的数据,将在下次访存时使用该绑定。 要取消绑定单个列(包括与 SQLBindFileToCol() 绑定的列),请致电 SQLBindCol()TargetValuePtr设置为NULL。 要取消所有列的绑定,应用程序应在 选项 输入设置为 SQL_UNBIND 的情况下调用 SQLFreeStmt()

应用程序必须确保为要检索的数据分配足够的存储空间。 如果缓冲区要包含可变长度数据,那么应用程序必须分配与绑定列的最大长度加 NULL 终止符一样多的存储空间。 否则,可能会截断数据。 如果缓冲区要包含固定长度的数据,那么 CLI 假定缓冲区的大小是 C 数据类型的长度。 如果指定了数据转换,那么可能影响所需大小。

如果确实发生字符串截断,则返回 SQL_SUCCESS_WITH_INFO,并将 StrLen_or_IndPtr 设置为可用于返回给应用程序的 TargetValuePtr实际大小。

SQL_ATTR_MAX_LENGTH 语句属性 (用于限制返回到应用程序的数据量) 也会影响截断。 应用程序可以通过调用 SQLSetStmtAttr() 并指定SQL_ATTR_MAX_LENGTH和所有可变长度列的最大返回长度,以及分配相同大小(加上空终止符) TargetValuePtr 缓冲区,来指定不报告截断。 如果列数据大于设定的最大长度,则在获取值时返回 SQL_SUCCESS,并在 StrLen_or_IndPtr 中返回最大长度,而不是实际长度。

如果要绑定的列是 SQL_GRAPHIC , SQL_VARGRAPHIC 或 SQL_LONGVARGRAPHIC 类型,那么可以将 TargetType 设置为 SQL_C_DBCHAR 或 SQL_C_CHAR。 如果 TargetType 为 SQL_C_DBCHAR,则 TargetValuePtr中获取的数据将以双字节空终止符进行空终止。 如果 TargetType 是 SQL_C_CHAR ,那么将不存在数据的 null 终止。 在这两种情况下 TargetValuePtrBufferLength 的长度以字节为单位,因此应为2的倍数。 还可以使用 PATCH1 关键字强制 CLI 以空终止图形字符串。

注意: 在以下情况下 StrLen_or_IndPtr 将返回SQL_NO_TOTAL:
  • SQL 类型是可变长度类型,并且
  • StrLen_or_IndPtrTargetValuePtr 是连续的,并且
  • 列类型为 NOT NULLABLE ,并且
  • 发生字符串截断。

描述符和 SQLBindCol

以下部分描述了 SQLBindCol() 如何与描述符交互。

注: 对一个语句进行 调用 SQLBindCol() 可能会影响其他语句。 当显式分配了与该语句相关联的 ARD 并且该 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_LENGTH , SQL_DESC_PRECISION 和 SQL_DESC_SCALE 中的一个或多个。
    • 将 SQL_DESC_OCTET_LENGTH 字段设置为 BufferLength的值。
    • 将 SQL_DESC_DATA_PTR 字段设置为 TargetValue的值。
    • 将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 字段

仅当这将增大 SQL_DESC_COUNT 的值时, SQLBindCol() 才会将 SQL_DESC_COUNT 设置为 ColumnNumber 参数的值。 如果 TargetValuePtr中的值为空指针,且 ColumnNumber中的值等于 SQL_DESC_COUNT(即当取消绑定最高绑定列时),则 SQL_DESC_COUNT 设置为剩余最高绑定列的编号。

有关 SQL_C_DEFAULT 的警告

要成功检索列数据,应用程序必须正确确定应用程序缓冲区中数据的长度和起始点。 当应用程序指定了明确 的TargetType 时,应用程序的错误很容易被发现。 但是,当应用程序指定了 SQL_C_DEFAULT TargetType 时, SQLBindCol() 可能会应用于与应用程序预期数据类型不同的列,这可能是由于元数据发生了变化,也可能是由于将代码应用于了不同的列。 在这种情况下,应用程序可能无法确定访存列数据的开始或长度。 这可能导致未报告的数据错误或内存违例。

返回码

  • SQL_SUCCESS
  • SQL_SUCCESS_WITH_INFO
  • SQL_ERROR
  • SQL_INVALID_HANDLE

Diagnostics

表 2. SQLBindCol SQLSTATEs
SQLSTATE 描述 说明
07009 描述符索引无效 为自变量 ColumnNumber 指定的值超过了结果集中的最大列数,或者指定的值小于 0。
40003 08S01 通信链路故障。 在功能完成之前,应用程序与数据源之间的通信链路失败。
58004 意外的系统故障。 不可恢复的系统错误。
HY001 内存分配故障。 Db2® CLI 无法分配支持执行或完成该功能所需的内存。 应用程序进程有可能已用完进程级内存。 请参阅操作系统配置以获取有关进程级别内存限制的信息。
HY003 程序类型超出范围。 TargetType 不是有效的数据类型或 SQL_C_DEFAULT。
HY010 函数顺序错误。 在 data-at-execute (SQLParamData()SQLPutData()) 操作中调用了此函数。

在 BEGIN 复合和 END 复合 SQL 操作中调用了该函数。

HY013 发生意外的内存处理错误。 Db2 CLI 无法访问支持执行或完成该功能所需的内存。
HY090 字符串或缓冲区长度无效。 为自变量 BufferLength 指定的值小于 1 ,而自变量 TargetType 为 SQL_C_CHAR , SQL_C_BINARY 或 SQL_C_DEFAULT。
HYC00 驱动程序不支持。 CLI 识别,但不支持自变量 TargetType 中指定的数据类型

指定了 LOB 定位器 C 数据类型,但连接的服务器不支持 LOB 数据类型。

注: 可能会在访存时报告与绑定列相关的其他诊断消息。

限制

仅当连接到支持大对象数据类型的服务器时, LOB 数据支持才可用。 如果应用程序尝试为不支持 LOB 定位器 C 数据类型的服务器指定该数据类型,那么将返回 SQLSTATE HYC00。

示例

 /* bind column 1 to variable */
 cliRC = SQLBindCol(hstmt, 1, SQL_C_SHORT, &deptnumb.val, 0, &deptnumb.ind);