SQLBindCol 函数SQLBindCol Function

Conformance
引入的版本: ODBC 1.0 标准符合性: ISO 92Version Introduced: ODBC 1.0 Standards Compliance: ISO 92

摘要Summary
SQLBindCol将应用程序数据缓冲区绑定到结果集中的列。SQLBindCol binds application data buffers to columns in the result set.

语法Syntax

  
SQLRETURN SQLBindCol(  
      SQLHSTMT       StatementHandle,  
      SQLUSMALLINT   ColumnNumber,  
      SQLSMALLINT    TargetType,  
      SQLPOINTER     TargetValuePtr,  
      SQLLEN         BufferLength,  
      SQLLEN *       StrLen_or_Ind);  

参数Arguments

StatementHandleStatementHandle
送语句句柄。[Input] Statement handle.

ColumnNumberColumnNumber
送要绑定的结果集列的编号。[Input] Number of the result set column to bind. 列按递增的列顺序编号,从0开始,其中列0是书签列。Columns are numbered in increasing column order starting at 0, where column 0 is the bookmark column. 如果未使用书签(即,SQL_ATTR_USE_BOOKMARKS 语句特性设置为 SQL_UB_OFF,则列号从1开始。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.

TargetTypeTargetType
送 *TargetValuePtr 缓冲区的 C 数据类型的标识符。[Input] The identifier of the C data type of the *TargetValuePtr buffer. 当从具有SQLFetchSQLFetchScrollSQLBulkOperationsSQLSetPos的数据源检索数据时,驱动程序会将数据转换为此类型;当它通过SQLBulkOperationsSQLSetPos将数据发送到数据源时,驱动程序将转换此类型的数据。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. 有关有效 C 数据类型和类型标识符的列表,请参阅附录 D:数据类型中的C 数据类型部分。For a list of valid C data types and type identifiers, see the C Data Types section in Appendix D: Data Types.

如果TargetType参数是 interval 数据类型,则默认间隔的默认间隔(2)和默认间隔秒精度(6),分别在 ARD 的 SQL_DESC_DATETIME_INTERVAL_PRECISION 和 SQL_DESC_PRECISION 字段中进行设置,用于数据。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. 如果使用了TargetType参数 SQL_C_NUMERIC,则将使用在 ARD 的 SQL_DESC_PRECISION 和 SQL_DESC_SCALE 字段中设置的默认精度(驱动程序定义)和默认刻度(0)作为数据。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. 如果任何默认的精度或小数位数不合适,则应用程序应通过调用SQLSetDescFieldSQLSetDescRec显式设置相应的描述符字段。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.

还可以指定扩展的 C 数据类型。You can also specify an extended C data type. 有关详细信息,请参阅ODBC 中的 C 数据类型For more information, see C Data Types in ODBC.

TargetValuePtrTargetValuePtr
[延迟的输入/输出]指向要绑定到列的数据缓冲区的指针。[Deferred Input/Output] Pointer to the data buffer to bind to the column. SQLFetchSQLFetchScroll返回此缓冲区中的数据。SQLFetch and SQLFetchScroll return data in this buffer. 当 SQL_FETCH_BY_BOOKMARK操作时, SQLBulkOperations将返回此缓冲区中的数据;当操作SQL_ADD 或 SQL_UPDATE_BY_BOOKMARK 时,它将从此缓冲区检索数据。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. 当 SQL_REFRESH操作时, SQLSetPos将返回此缓冲区中的数据;当 SQL_UPDATE操作时,它将从该缓冲区检索数据。SQLSetPos returns data in this buffer when Operation is SQL_REFRESH; it retrieves data from this buffer when Operation is SQL_UPDATE.

如果 TargetValuePtr 为 null 指针,则驱动程序将为列解除数据缓冲区的绑定。If TargetValuePtr is a null pointer, the driver unbinds the data buffer for the column. 应用程序可以通过使用 SQL_UNBIND 选项调用SQLFreeStmt来解除所有列的绑定。An application can unbind all columns by calling SQLFreeStmt with the SQL_UNBIND option. 如果对SQLBindCol的调用中的 TargetValuePtr 参数为 Null 指针,但StrLen_or_IndPtr参数是有效的,则应用程序可以解除列的数据缓冲区的绑定,但仍具有绑定到列的长度/指示器缓冲区负值.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.

BufferLengthBufferLength
送 *TargetValuePtr* 缓冲区的长度(以字节为单位)。[Input] Length of the *TargetValuePtr buffer in bytes.

当驱动程序返回长度可变的数据(如字符或二进制数据)时,驱动程序使用BufferLength来避免写入超过 *TargetValuePtr缓冲区的末尾。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. 请注意,当驱动程序将字符数据返回到 *TargetValuePtr时,驱动程序会对 null 终止字符进行计数。Notice that the driver counts the null-termination character when it returns character data to *TargetValuePtr. *TargetValuePtr因此必须包含空间的 null 终止字符或驱动程序将截断数据。*TargetValuePtr must therefore contain space for the null-termination character or the driver will truncate the data.

当驱动程序返回固定长度的数据(如整数或日期结构)时,驱动程序将忽略BufferLength ,并假定缓冲区足以容纳数据。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.

BufferLength小于0但当BufferLength为0时, SQLBindCol返回 SQLSTATE HY090 (无效的字符串或缓冲区长度)。SQLBindCol returns SQLSTATE HY090 (Invalid string or buffer length) when BufferLength is less than 0 but not when BufferLength is 0. 但是,如果TargetType指定了字符类型,则应用程序不应将BufferLength设置为0,因为在这种情况下,符合 ISO CLI 的驱动程序将返回 SQLSTATE HY090 (无效的字符串或缓冲区长度)。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.

StrLen_or_IndPtrStrLen_or_IndPtr
[延迟的输入/输出]指向要绑定到列的长度/指示器缓冲区的指针。[Deferred Input/Output] Pointer to the length/indicator buffer to bind to the column. SQLFetchSQLFetchScroll返回此缓冲区中的值。SQLFetch and SQLFetchScroll return a value in this buffer. 操作SQL_ADD、SQL_UPDATE_BY_BOOKMARK 或 SQL_DELETE_BY_BOOKMARK 时, SQLBulkOperations从该缓冲区检索值。SQLBulkOperations retrieves a value from this buffer when Operation is SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK. 当 SQL_FETCH_BY_BOOKMARK操作时, SQLBulkOperations将在此缓冲区中返回一个值。SQLBulkOperations returns a value in this buffer when Operation is SQL_FETCH_BY_BOOKMARK. 当 SQL_REFRESH操作时, SQLSetPos将在此缓冲区中返回值;当 SQL_UPDATE操作时,它将从此缓冲区检索值。SQLSetPos returns a value in this buffer when Operation is SQL_REFRESH; it retrieves a value from this buffer when Operation is SQL_UPDATE.

SQLFetchSQLFetchScrollSQLBulkOperationsSQLSetPos可以返回长度/指示器缓冲区中的以下值: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_TOTALSQL_NO_TOTAL

  • SQL_NULL_DATASQL_NULL_DATA

应用程序可以在长度/指示器缓冲区中放置以下值,以便与SQLBulkOperationsSQLSetPos一起使用: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_NTSSQL_NTS

  • SQL_NULL_DATASQL_NULL_DATA

  • SQL_DATA_AT_EXECSQL_DATA_AT_EXEC

  • SQL_LEN_DATA_AT_EXEC 宏的结果The result of the SQL_LEN_DATA_AT_EXEC macro

  • SQL_COLUMN_IGNORESQL_COLUMN_IGNORE

如果指示器缓冲区和长度缓冲区是单独的缓冲区,则指示器缓冲区只能返回 SQL_NULL_DATA,而长度缓冲区可以返回所有其他值。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.

有关详细信息,请参阅SQLBulkOperations 函数SQLFetch 函数SQLSetPos 函数使用长度/指示器值For more information, see SQLBulkOperations Function, SQLFetch Function, SQLSetPos Function, and Using Length/Indicator Values.

如果StrLen_or_IndPtr为 null 指针,则不使用长度或指示器值。If StrLen_or_IndPtr is a null pointer, no length or indicator value is used. 这是提取数据时出错,数据为 NULL。This is an error when fetching data and the data is NULL.

如果你的应用程序将在64位操作系统上运行,请参阅ODBC 64 位信息See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.

返回Returns

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_ERROR 或 SQL_INVALID_HANDLE。SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE.

诊断Diagnostics

SQLBindCol返回 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO 时,可以通过使用HandleType的 SQL_HANDLE_STMT 和StatementHandle句柄调用SQLGetDiagRec来获取关联的 SQLSTATE 值。When SQLBindCol returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of StatementHandle. 下表列出了通常由SQLBindCol返回的 SQLSTATE 值,并对该函数的上下文中的每个值进行了说明:"(DM)" 表示法位于驱动程序管理器返回的 SQLSTATEs 的说明之前。The following table lists the SQLSTATE values typically returned by SQLBindCol and explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by the Driver Manager. 除非另有说明,否则与每个 SQLSTATE 值相关联的返回代码将 SQL_ERROR。The return code associated with each SQLSTATE value is SQL_ERROR, unless noted otherwise.

SQLSTATESQLSTATE ErrorError 描述Description
0100001000 一般警告General warning 驱动程序特定的信息性消息。Driver-specific informational message. (函数返回 SQL_SUCCESS_WITH_INFO。)(Function returns SQL_SUCCESS_WITH_INFO.)
0700607006 受限制的数据类型属性冲突Restricted data type attribute violation (DM) ColumnNumber参数为0,但TargetType参数不是 SQL_C_BOOKMARK 或 SQL_C_VARBOOKMARK。(DM) The ColumnNumber argument was 0, and the TargetType argument was not SQL_C_BOOKMARK or SQL_C_VARBOOKMARK.
0700907009 描述符索引无效Invalid descriptor index 为参数ColumnNumber指定的值超出了结果集中的最大列数。The value specified for the argument ColumnNumber exceeded the maximum number of columns in the result set.
HY000HY000 一般错误General error 发生了一个错误,该错误没有特定的 SQLSTATE,没有为其定义实现特定的 SQLSTATE。An error occurred for which there was no specific SQLSTATE and for which no implementation-specific SQLSTATE was defined. *MessageText缓冲区中的SQLGetDiagRec返回的错误消息描述了错误及其原因。The error message returned by SQLGetDiagRec in the *MessageText buffer describes the error and its cause.
HY001HY001 内存分配错误Memory allocation error 驱动程序无法分配支持执行或完成此函数所需的内存。The driver was unable to allocate memory that is required to support execution or completion of the function.
HY003HY003 应用程序缓冲区类型无效Invalid application buffer type 参数TargetType既不是有效的数据类型,也不是 SQL_C_DEFAULT。The argument TargetType was neither a valid data type nor SQL_C_DEFAULT.
HY010HY010 函数序列错误Function sequence error (DM)为与StatementHandle关联的连接句柄调用了异步执行的函数。(DM) An asynchronously executing function was called for the connection handle that is associated with the StatementHandle. 调用SQLBindCol时仍在执行此异步函数。This asynchronous function was still executing when SQLBindCol was called.

StatementHandle调用了SQLExecuteSQLExecDirectSQLMoreResults ,并返回 SQL_PARAM_DATA_AVAILABLE。(DM) SQLExecute, SQLExecDirect, or SQLMoreResults was called for the StatementHandle and returned SQL_PARAM_DATA_AVAILABLE. 在检索所有流式处理参数的数据之前调用此函数。This function was called before data was retrieved for all streamed parameters.

(DM)为StatementHandle调用了异步执行的函数,并且在调用此函数时仍在执行该函数。(DM) An asynchronously executing function was called for the StatementHandle and was still executing when this function was called.

(DM) SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos调用了StatementHandle并返回 SQL_NEED_DATA。(DM) SQLExecute, SQLExecDirect, SQLBulkOperations, or SQLSetPos was called for the StatementHandle and returned SQL_NEED_DATA. 在为所有执行时数据参数或列发送数据之前,将调用此函数。This function was called before data was sent for all data-at-execution parameters or columns.
HY013HY013 内存管理错误Memory management error 未能处理函数调用,原因可能是由于内存不足而无法访问基础内存对象。The function call could not be processed because the underlying memory objects could not be accessed, possibly because of low memory conditions.
HY090HY090 字符串或缓冲区长度无效Invalid string or buffer length (DM)为参数BufferLength指定的值小于0。(DM) The value specified for the argument BufferLength was less than 0.

(DM)驱动程序是一个 ODBC 2。x驱动程序, ColumnNumber参数设置为0,为参数BufferLength指定的值不等于4。(DM) The driver was an ODBC 2.x driver, the ColumnNumber argument was set to 0, and the value specified for the argument BufferLength was not equal to 4.
HY117HY117 由于未知的事务状态,连接被挂起。Connection is suspended due to unknown transaction state. 仅允许断开连接和只读函数。Only disconnect and read-only functions are allowed. (DM)有关挂起状态的详细信息,请参阅SQLEndTran 函数(DM) For more information about suspended state, see SQLEndTran Function.
HYC00HYC00 未实现的可选功能Optional feature not implemented 驱动程序或数据源不支持通过TargetType参数和相应列的特定于驱动程序的 SQL 数据类型组合指定的转换。The driver or data source does not support the conversion specified by the combination of the TargetType argument and the driver-specific SQL data type of the corresponding column.

参数ColumnNumber为0,驱动程序不支持书签。The argument ColumnNumber was 0 and the driver does not support bookmarks.

驱动程序仅支持 ODBC 2。x和参数TargetType为以下其中一项:The driver supports only ODBC 2.x and the argument TargetType was one of the following:

SQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINTSQL_C_NUMERIC SQL_C_SBIGINT SQL_C_UBIGINT

在附录 D:数据类型中, c 数据类型中列出的任何时间间隔 c 数据类型。and any of the interval C data types listed in C Data Types in Appendix D: Data Types.

驱动程序仅支持3.50 之前的 ODBC 版本,并 SQL_C_GUID 参数TargetTypeThe driver only supports ODBC versions prior to 3.50, and the argument TargetType was SQL_C_GUID.
HYT01HYT01 连接超时已过期Connection timeout expired 连接超时期限在数据源响应请求之前过期。The connection timeout period expired before the data source responded to the request. 连接超时期限通过SQLSetConnectAttr设置,SQL_ATTR_CONNECTION_TIMEOUT。The connection timeout period is set through SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001IM001 驱动程序不支持此功能Driver does not support this function (DM)与StatementHandle关联的驱动程序不支持该函数。(DM) The driver associated with the StatementHandle does not support the function.

注释Comments

SQLBindCol用于将结果集中的列关联或绑定到应用程序中的数据缓冲区和长度/指示器缓冲区。SQLBindCol is used to associate, or bind, columns in the result set to data buffers and length/indicator buffers in the application. 当应用程序调用SQLFetchSQLFetchScrollSQLSetPos获取数据时,驱动程序将为指定缓冲区中的绑定列返回数据;有关详细信息,请参阅SQLFetch 函数When the application calls SQLFetch, SQLFetchScroll, or SQLSetPos to fetch data, the driver returns the data for the bound columns in the specified buffers; for more information, see SQLFetch Function. 当应用程序调用SQLBulkOperations更新或插入行或SQLSetPos以更新行时,驱动程序将从指定的缓冲区中检索绑定列的数据;有关详细信息,请参阅SQLBulkOperations 函数SQLSetPos 函数When the application calls SQLBulkOperations to update or insert a row or SQLSetPos to update a row, the driver retrieves the data for the bound columns from the specified buffers; for more information, see SQLBulkOperations Function or SQLSetPos Function. 有关绑定的详细信息,请参阅检索结果(基本)For more information about binding, see Retrieving Results (Basic).

请注意,不需要绑定列来从它们中检索数据。Notice that columns do not have to be bound to retrieve data from them. 应用程序还可以调用SQLGetData来检索列中的数据。An application can also call SQLGetData to retrieve data from columns. 尽管可以绑定行中的某些列并为其他列调用SQLGetData ,但这可能会受到某些限制。Although it is possible to bind some columns in a row and call SQLGetData for others, this is subject to some restrictions. 有关详细信息,请参阅SQLGetDataFor more information, see SQLGetData.

绑定、取消绑定和重新绑定列Binding, Unbinding, and Rebinding Columns

即使已从结果集中提取数据,也可以随时绑定、取消绑定或重新绑定列。A column can be bound, unbound, or rebound at any time, even after data has been fetched from the result set. 新绑定将在下一次调用使用绑定的函数时生效。The new binding takes effect the next time that a function that uses bindings is called. 例如,假设应用程序绑定结果集中的列并调用SQLFetchFor example, suppose an application binds the columns in a result set and calls SQLFetch. 驱动程序将返回绑定缓冲区中的数据。The driver returns the data in the bound buffers. 现在,假设应用程序将列绑定到一组不同的缓冲区。Now suppose the application binds the columns to a different set of buffers. 该驱动程序不会将提取行的数据放入新绑定的缓冲区中。The driver does not put the data for the just-fetched row in the newly bound buffers. 相反,它会一直等待,直到再次调用SQLFetch ,然后将数据放置到新绑定的缓冲区中的下一行。Instead, it waits until SQLFetch is called again and then places the data for the next row in the newly bound buffers.

备注

应始终在将列绑定到列0之前设置语句属性 SQL_ATTR_USE_BOOKMARKS。The statement attribute SQL_ATTR_USE_BOOKMARKS should always be set before binding a column to column 0. 这不是必需的,但强烈建议这样做。This is not required but is strongly recommended.

绑定列Binding Columns

若要绑定列,应用程序将调用SQLBindCol并传递列号、类型、地址和数据缓冲区的长度以及长度/指示器缓冲区的地址。To bind a column, an application calls SQLBindCol and passes the column number, type, address, and length of a data buffer, and the address of a length/indicator buffer. 有关如何使用这些地址的信息,请参阅本部分后面的 "缓冲区地址"。For information about how these addresses are used, see "Buffer Addresses," later in this section. 有关绑定列的详细信息,请参阅Using SQLBindColFor more information about binding columns, see Using SQLBindCol.

这些缓冲区的使用会延迟;也就是说,应用程序将其绑定到SQLBindCol中,但驱动程序将从其他函数(即SQLBulkOperationsSQLFetchSQLFetchScrollSQLSetPos)进行访问。The use of these buffers is deferred; that is, the application binds them in SQLBindCol but the driver accesses them from other functions - namely SQLBulkOperations, SQLFetch, SQLFetchScroll, or SQLSetPos. 应用程序负责确保只要绑定保持有效, SQLBindCol中指定的指针仍然有效。It is the application's responsibility to make sure that the pointers specified in SQLBindCol remain valid as long as the binding remains in effect. 如果应用程序允许这些指针变为无效(例如,它释放缓冲区,然后调用一个预期其有效的函数),则结果是不确定的。If the application allows these pointers to become invalid - for example, it frees a buffer - and then calls a function that expects them to be valid, the consequences are undefined. 有关详细信息,请参阅延迟缓冲区For more information, see Deferred Buffers.

绑定将保持有效,直到它被新绑定替换、列未绑定或释放该语句。The binding remains in effect until it is replaced by a new binding, the column is unbound, or the statement is freed.

拆散列Unbinding Columns

若要取消对单个列的绑定,应用程序将调用SQLBindCol ,并将ColumnNumber设置为该列的数目,并将TargetValuePtr设置为 null 指针。To unbind a single column, an application calls SQLBindCol with ColumnNumber set to the number of that column and TargetValuePtr set to a null pointer. 如果ColumnNumber引用了未绑定列,则SQLBindCol仍返回 SQL_SUCCESS。If ColumnNumber refers to an unbound column, SQLBindCol still returns SQL_SUCCESS.

若要取消绑定所有列,应用程序将调用SQLFreeStmt ,并将fOption设置为 SQL_UNBIND。To unbind all columns, an application calls SQLFreeStmt with fOption set to SQL_UNBIND. 还可以通过将 ARD 的 SQL_DESC_COUNT 字段设置为零来实现此目的。This can also be accomplished by setting the SQL_DESC_COUNT field of the ARD to zero.

重新绑定列Rebinding Columns

应用程序可以执行以下两个操作之一来更改绑定:An application can perform either of two operations to change a binding:

  • 调用SQLBindCol为已绑定的列指定新绑定。Call SQLBindCol to specify a new binding for a column that is already bound. 驱动程序用新的绑定覆盖旧的绑定。The driver overwrites the old binding with the new one.

  • 指定要添加到由对SQLBindCol的绑定调用指定的缓冲区地址的偏移量。Specify an offset to be added to the buffer address that was specified by the binding call to SQLBindCol. 有关详细信息,请参阅下一节 "绑定偏移量"。For more information, see the next section, "Binding Offsets."

绑定偏移量Binding Offsets

绑定偏移量是在取消引用之前,添加到数据和长度/指示器缓冲区(在TargetValuePtrStrLen_or_IndPtr参数中指定)的地址的值。A binding offset is a value that is added to the addresses of the data and length/indicator buffers (as specified in the TargetValuePtr and StrLen_or_IndPtr argument) before they are dereferenced. 使用偏移量时,绑定是应用程序缓冲区布局方式的 "模板",应用程序可以通过更改偏移量将此 "模板" 移到不同的内存区域。When offsets are used, the bindings are a "template" of how the application's buffers are laid out, and the application can move this "template" to different areas of memory by changing the offset. 由于每个绑定中的每个地址都添加了相同的偏移量,因此每个缓冲区集中的不同列的缓冲区间的相对偏移量必须相同。Because the same offset is added to each address in each binding, the relative offsets between buffers for different columns must be the same within each set of buffers. 当使用按行绑定时,这始终为 true;应用程序必须仔细地布局其缓冲区,以便在使用按列绑定时,此属性为 true。This is always true when row-wise binding is used; the application must carefully lay out its buffers for this to be true when column-wise binding is used.

使用绑定偏移量与通过调用SQLBindCol重新绑定列基本相同。Using a binding offset has basically the same effect as rebinding a column by calling SQLBindCol. 不同之处是,对SQLBindCol的新调用指定了数据缓冲区和长度/指示器缓冲区的新地址,而使用绑定偏移量不会更改地址,只是向其添加偏移量。The difference is that a new call to SQLBindCol specifies new addresses for the data buffer and length/indicator buffer, whereas use of a binding offset does not change the addresses but just adds an offset to them. 应用程序可以在需要时指定新的偏移量,并且始终会将此偏移量添加到最初绑定的地址。The application can specify a new offset whenever it wants, and this offset is always added to the originally bound addresses. 尤其是,如果偏移量设置为0,或者如果语句特性设置为 null 指针,则驱动程序将使用最初绑定的地址。In particular, if the offset is set to 0 or if the statement attribute is set to a null pointer, the driver uses the originally bound addresses.

为了指定绑定偏移量,应用程序将 SQL_ATTR_ROW_BIND_OFFSET_PTR 语句特性设置为 SQLINTEGER 缓冲区的地址。To specify a binding offset, the application sets the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to the address of an SQLINTEGER buffer. 在应用程序调用使用绑定的函数之前,它会在此缓冲区中的偏移量(以字节为单位)。Before the application calls a function that uses bindings, it puts an offset in bytes in this buffer. 为了确定要使用的缓冲区的地址,驱动程序将偏移量添加到绑定中的地址。To determine the address of the buffer to use, the driver adds the offset to the address in the binding. 地址与偏移量之和必须是有效地址,但偏移量的添加地址不一定有效。The sum of the address and the offset must be a valid address, but the address to which the offset is added does not have to be valid. 有关如何使用绑定偏移量的详细信息,请参阅本部分后面的 "缓冲区地址"。For more information about how binding offsets are used, see "Buffer Addresses," later in this section.

绑定数组Binding Arrays

如果行集大小(SQL_ATTR_ROW_ARRAY_SIZE 语句特性的值)大于1,则应用程序将绑定缓冲区数组而不是单个缓冲区。If the rowset size (the value of the SQL_ATTR_ROW_ARRAY_SIZE statement attribute) is greater than 1, the application binds arrays of buffers instead of single buffers. 有关详细信息,请参阅块游标For more information, see Block Cursors.

应用程序可以通过两种方式绑定数组:The application can bind arrays in two ways:

  • 将数组绑定到每个列。Bind an array to each column. 这称为按列绑定,因为每个数据结构(数组)都包含单个列的数据。This is referred to as column-wise binding because each data structure (array) contains data for a single column.

  • 定义一个结构来保存整行的数据,并绑定这些结构的数组。Define a structure to hold the data for a whole row and bind an array of these structures. 这称为按行绑定,因为每个数据结构包含单个行的数据。This is referred to as row-wise binding because each data structure contains the data for a single row.

每个缓冲区数组都必须具有至少与行集大小相同的元素。Each array of buffers must have at least as many elements as the size of the rowset.

备注

应用程序必须验证对齐是否有效。An application must verify that alignment is valid. 有关对齐注意事项的详细信息,请参阅对齐For more information about alignment considerations, see Alignment.

按列绑定Column-Wise Binding

在按列绑定中,应用程序将单独的数据和长度/指示器数组绑定到每个列。In column-wise binding, the application binds separate data and length/indicator arrays to each column.

若要使用按列绑定,应用程序首先将 SQL_ATTR_ROW_BIND_TYPE 语句特性设置为 SQL_BIND_BY_COLUMN。To use column-wise binding, the application first sets the SQL_ATTR_ROW_BIND_TYPE statement attribute to SQL_BIND_BY_COLUMN. (这是默认值。)对于每个要绑定的列,应用程序执行以下步骤:(This is the default.) For each column to be bound, the application performs the following steps:

  1. 分配数据缓冲区数组。Allocates a data buffer array.

  2. 分配长度/指示器缓冲区的数组。Allocates an array of length/indicator buffers.

    备注

    当使用按列绑定时,如果应用程序直接写入描述符,则可以使用单独的数组作为长度和指示器数据。If the application writes directly to descriptors when column-wise binding is used, separate arrays can be used for length and indicator data.

  3. 调用具有以下参数的SQLBindColCalls SQLBindCol with the following arguments:

    • TargetType是数据缓冲区数组中单个元素的类型。TargetType is the type of a single element in the data buffer array.

    • TargetValuePtr是数据缓冲区数组的地址。TargetValuePtr is the address of the data buffer array.

    • BufferLength是数据缓冲区数组中单个元素的大小。BufferLength is the size of a single element in the data buffer array. 当数据为固定长度数据时,将忽略BufferLength参数。The BufferLength argument is ignored when the data is fixed-length data.

    • StrLen_or_IndPtr是长度/指示器数组的地址。StrLen_or_IndPtr is the address of the length/indicator array.

有关如何使用此信息的详细信息,请参阅本部分后面的 "缓冲区地址"。For more information about how this information is used, see "Buffer Addresses," later in this section. 有关按列绑定的详细信息,请参阅按列绑定For more information about column-wise binding, see Column-Wise Binding.

按行绑定Row-Wise Binding

在按行绑定中,应用程序将定义一个结构,该结构包含每个要绑定的列的数据和长度/指示器缓冲区。In row-wise binding, the application defines a structure that contains data and length/indicator buffers for each column to be bound.

若要使用按行绑定,应用程序需要执行以下步骤:To use row-wise binding, the application performs the following steps:

  1. 定义用于保存单个数据行(包括数据和长度/指示器缓冲区)的结构,并分配这些结构的数组。Defines a structure to hold a single row of data (including both data and length/indicator buffers) and allocates an array of these structures.

    备注

    当使用按行绑定时,如果应用程序直接写入描述符,则可以将单独的字段用于长度和指示器数据。If the application writes directly to descriptors when row-wise binding is used, separate fields can be used for length and indicator data.

  2. 将 SQL_ATTR_ROW_BIND_TYPE 语句特性设置为包含单个数据行的结构的大小,或设置为结果列将绑定到的缓冲区的实例大小的。Sets the SQL_ATTR_ROW_BIND_TYPE statement attribute to the size of the structure that contains a single row of data or to the size of an instance of a buffer into which the results columns will be bound. 长度必须包含所有绑定列的空间以及结构或缓冲区的任何填充,以确保当绑定列的地址递增指定的长度时,结果将指向下一行中同一列的开头。The length must include space for all the bound columns, and any padding of the structure or buffer, to make sure that when the address of a bound column is incremented with the specified length, the result will point to the beginning of the same column in the next row. 在 ANSI C 中使用sizeof运算符时,此行为是保证的。When using the sizeof operator in ANSI C, this behavior is guaranteed.

  3. 对于每个要绑定的列,调用SQLBindCol ,并提供以下参数:Calls SQLBindCol with the following arguments for each column to be bound:

    • TargetType是要绑定到列的数据缓冲区成员的类型。TargetType is the type of the data buffer member to be bound to the column.

    • TargetValuePtr是第一个数组元素中的数据缓冲区成员的地址。TargetValuePtr is the address of the data buffer member in the first array element.

    • BufferLength是数据缓冲区成员的大小。BufferLength is the size of the data buffer member.

    • StrLen_or_IndPtr是要绑定的长度/指示器成员的地址。StrLen_or_IndPtr is the address of the length/indicator member to be bound.

有关如何使用此信息的详细信息,请参阅本部分后面的 "缓冲区地址"。For more information about how this information is used, see "Buffer Addresses," later in this section. 有关按列绑定的详细信息,请参阅按行绑定For more information about column-wise binding, see Row-Wise Binding.

缓冲区地址Buffer Addresses

缓冲区地址是数据或长度/指示器缓冲区的实际地址。The buffer address is the actual address of the data or length/indicator buffer. 驱动程序在写入缓冲区之前(例如在提取时)计算缓冲区地址。The driver calculates the buffer address just before it writes to the buffers (such as during fetch time). 它是通过下面的公式计算的,它使用 TargetValuePtrStrLen_or_IndPtr参数中指定的地址、绑定偏移量和行号:It is calculated from the following formula, which uses the addresses specified in the TargetValuePtr and StrLen_or_IndPtr arguments, the binding offset, and the row number:

绑定地址 + 绑定偏移量+ ((行号-1) x元素大小Bound Address + Binding Offset + ((Row Number - 1) x Element Size)

公式变量的定义位置如下表中所述。where the formula's variables are defined as described in the following table.

变量Variable 描述Description
绑定地址Bound Address 对于数据缓冲区,为SQLBindCol中的 TargetValuePtr 参数指定的地址。For data buffers, the address specified with the TargetValuePtr argument in SQLBindCol.

对于长度/指示器缓冲区,为SQLBindCol中的StrLen_or_IndPtr参数指定的地址。For length/indicator buffers, the address specified with the StrLen_or_IndPtr argument in SQLBindCol. 有关详细信息,请参阅 "描述符和 SQLBindCol" 部分中的 "其他注释"。For more information, see "Additional Comments" in the "Descriptors and SQLBindCol" section.

如果绑定地址是0,则不会返回任何数据值,即使之前公式计算的地址不为零。If the bound address is 0, no data value is returned, even if the address as calculated by the previous formula is nonzero.
绑定偏移量Binding Offset 如果使用按行绑定,则使用 SQL_ATTR_ROW_BIND_OFFSET_PTR 语句特性指定的地址上存储的值。If row-wise binding is used, the value stored at the address specified with the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute.

如果使用按列绑定或 SQL_ATTR_ROW_BIND_OFFSET_PTR 语句特性的值为 null 指针,则绑定偏移量为0。If column-wise binding is used or if the value of the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute is a null pointer, Binding Offset is 0.
行号Row Number 行集中从1开始的行号。The 1-based number of the row in the rowset. 对于单行读取(默认值),此值为1。For single-row fetches, which are the default, this is 1.
元素大小Element Size 绑定数组中元素的大小。The size of an element in the bound array.

如果使用按列绑定,则为长度/指示器缓冲区的sizeof (SQLINTEGER)If column-wise binding is used, this is sizeof(SQLINTEGER) for length/indicator buffers. 对于数据缓冲区,如果数据类型为可变长度,则为BufferLength参数的值 ; 如果数据类型为固定长度,则为数据类型的大小。For data buffers, it is the value of the BufferLength argument in SQLBindCol if the data type is variable length, and the size of the data type if the data type is fixed length.

如果使用按行绑定,则这是数据和长度/指示器缓冲区的 SQL_ATTR_ROW_BIND_TYPE 语句特性的值。If row-wise binding is used, this is the value of the SQL_ATTR_ROW_BIND_TYPE statement attribute for both data and length/indicator buffers.

描述符和 SQLBindColDescriptors and SQLBindCol

以下各节介绍了SQLBindCol如何与描述符交互。The following sections describe how SQLBindCol interacts with descriptors.

注意

对一个语句调用SQLBindCol可能会影响其他语句。Calling SQLBindCol for one statement can affect other statements. 如果与该语句关联的 ARD 已显式分配并与其他语句相关联,则会发生这种情况。This occurs when the ARD associated with the statement is explicitly allocated and is also associated with other statements. 由于SQLBindCol修改了描述符,因此修改应用于与此描述符关联的所有语句。Because SQLBindCol modifies the descriptor, the modifications apply to all statements with which this descriptor is associated. 如果这不是所需的行为,应用程序应在调用SQLBindCol之前,将此描述符与其他语句取消关联。If this is not the required behavior, the application should dissociate this descriptor from the other statements before it calls SQLBindCol.

参数映射Argument Mappings

从概念上讲, SQLBindCol按顺序执行以下步骤:Conceptually, SQLBindCol performs the following steps in sequence:

  1. 调用SQLGetStmtAttr以获取 ARD 句柄。Calls SQLGetStmtAttr to obtain the ARD handle.

  2. 调用SQLGetDescField以获取此描述符的 SQL_DESC_COUNT 字段,如果ColumnNumber参数中的值超出 SQL_DESC_COUNT 的值,则调用SQLSetDescField以将 SQL_DESC_COUNT 的值增加到ColumnNumberCalls SQLGetDescField to get this descriptor's SQL_DESC_COUNT field, and if the value in the ColumnNumber argument exceeds the value of SQL_DESC_COUNT, calls SQLSetDescField to increase the value of SQL_DESC_COUNT to ColumnNumber.

  3. 多次调用SQLSetDescField ,将值分配给 ARD 的以下字段:Calls SQLSetDescField multiple times to assign values to the following fields of the ARD:

    • 将 SQL_DESC_TYPE 和 SQL_DESC_CONCISE_TYPE 设置为TargetType的值,只不过当targettype是 datetime 或 interval 子类型的简洁标识符之一时,它会将 SQL_DESC_TYPE 分别设置为 SQL_DATETIME 或 SQL_INTERVAL;将 SQL_DESC_CONCISE_TYPE 设置为简洁标识符;并将 SQL_DESC_DATETIME_INTERVAL_CODE 设置为相应的 DATETIME 或 INTERVAL 子代码。Sets SQL_DESC_TYPE and SQL_DESC_CONCISE_TYPE to the value of TargetType, except that if TargetType is one of the concise identifiers of a datetime or interval subtype, it sets SQL_DESC_TYPE to SQL_DATETIME or SQL_INTERVAL, respectively; sets SQL_DESC_CONCISE_TYPE to the concise identifier; and sets SQL_DESC_DATETIME_INTERVAL_CODE to the corresponding datetime or interval subcode.

    • 根据TargetType的需要,设置一个或多个 SQL_DESC_LENGTH、SQL_DESC_PRECISION、SQL_DESC_SCALE 和 SQL_DESC_DATETIME_INTERVAL_PRECISION。Sets one or more of SQL_DESC_LENGTH, SQL_DESC_PRECISION, SQL_DESC_SCALE, and SQL_DESC_DATETIME_INTERVAL_PRECISION, as appropriate for TargetType.

    • 将 SQL_DESC_OCTET_LENGTH 字段设置为BufferLength的值。Sets the SQL_DESC_OCTET_LENGTH field to the value of BufferLength.

    • 将 SQL_DESC_DATA_PTR 字段设置为TargetValue的值。Sets the SQL_DESC_DATA_PTR field to the value of TargetValue.

    • 将 SQL_DESC_INDICATOR_PTR 字段设置为StrLen_or_Ind的值。Sets the SQL_DESC_INDICATOR_PTR field to the value of StrLen_or_Ind. (请参阅下一段。)(See the following paragraph.)

    • 将 SQL_DESC_OCTET_LENGTH_PTR 字段设置为StrLen_or_Ind的值。Sets the SQL_DESC_OCTET_LENGTH_PTR field to the value of StrLen_or_Ind. (请参阅下一段。)(See the following paragraph.)

StrLen_or_Ind参数引用的变量用于指示器和长度信息。The variable that the StrLen_or_Ind argument refers to is used for both indicator and length information. 如果提取遇到列的 null 值,则它将 SQL_NULL_DATA 存储在此变量中;否则,它会将数据长度存储在此变量中。If a fetch encounters a null value for the column, it stores SQL_NULL_DATA in this variable; otherwise, it stores the data length in this variable. 将 null 指针作为StrLen_or_Ind传递会使提取操作返回数据长度,但如果遇到 null 值并且无法返回 SQL_NULL_DATA,则会使提取失败。Passing a null pointer as StrLen_or_Ind keeps the fetch operation from returning the data length but makes the fetch fail if it encounters a null value and has no way to return SQL_NULL_DATA.

如果对SQLBindCol的调用失败,则它将在 ARD 中设置的描述符字段的内容是未定义的,并且 ARD 的 SQL_DESC_COUNT 字段的值不变。If the call to SQLBindCol fails, the content of the descriptor fields that it would have set in the ARD are undefined and the value of the SQL_DESC_COUNT field of the ARD is unchanged.

计数字段的隐式重置Implicit Resetting of COUNT Field

仅当这会增加 SQL_DESC_COUNT 的值时, SQLBindCol才会将 SQL_DESC_COUNT 设置为ColumnNumber参数的值。SQLBindCol sets SQL_DESC_COUNT to the value of the ColumnNumber argument only when this would increase the value of SQL_DESC_COUNT. 如果TargetValuePtr参数中的值为 null 指针,并且ColumnNumber参数中的值等于 SQL_DESC_COUNT (即,解除绑定最大的列时),则 SQL_DESC_COUNT 设置为剩余的最大绑定列的数目。If the value in the TargetValuePtr argument is a null pointer and the value in the ColumnNumber argument is equal to SQL_DESC_COUNT (that is, when unbinding the highest bound column), then SQL_DESC_COUNT is set to the number of the highest remaining bound column.

关于 SQL_DEFAULT 的注意事项Cautions Regarding SQL_DEFAULT

若要成功检索列数据,应用程序必须确定应用程序缓冲区中数据的长度和起点。To retrieve column data successfully, the application must determine correctly the length and starting point of the data in the application buffer. 当应用程序指定显式TargetType时,可以轻松检测到应用程序误解。When the application specifies an explicit TargetType, application misconceptions are easily detected. 但是,当应用程序指定 SQL_DEFAULT 的TargetType时, SQLBindCol可应用于应用程序所需的不同数据类型的列,无论是对元数据的更改还是通过将代码应用于其他列。However, when the application specifies a TargetType of SQL_DEFAULT, SQLBindCol can be applied to a column of a different data type from the one intended by the application, either from changes to the metadata or by applying the code to a different column. 在这种情况下,应用程序可能不会始终确定提取的列数据的开始或长度。In this case, the application may not always determine the start or length of the fetched column data. 这可能会导致未报告的数据错误或内存冲突。This may lead to unreported data errors or memory violations.

代码示例Code Example

在下面的示例中,应用程序对 Customers 表执行SELECT语句以返回客户 id、名称和电话号码的结果集,按名称排序。In the following example, an application executes a SELECT statement on the Customers table to return a result set of the customer IDs, names, and phone numbers, sorted by name. 然后,它调用SQLBindCol将数据的列绑定到本地缓冲区。It then calls SQLBindCol to bind the columns of data to local buffers. 最后,应用程序通过SQLFetch提取每个数据行,并打印每个客户的姓名、ID 和电话号码。Finally, the application fetches each row of data with SQLFetch and prints each customer's name, ID, and phone number.

有关更多代码示例,请参阅SQLBulkOperations 函数SQLColumns 函数SQLFetchScroll 函数SQLSetPos 函数For more code examples, see SQLBulkOperations Function, SQLColumns Function, SQLFetchScroll Function, and SQLSetPos Function.

// 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 20  
  
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_CHAR, &sCustID, 100, &cbCustID);  
                  retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);  
                  retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN, &cbPhone);   
  
                  // Fetch and print each row of data. On an error, display a message and exit.  
                  for (i ; ; i++) {  
                     retcode = SQLFetch(hstmt);  
                     if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO)  
                        show_error();  
                     if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
                        wprintf(L"%d: %S %S %S\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 程序Also see, Sample ODBC Program.

有关信息For information about 请参阅See
返回有关结果集中的列的信息Returning information about a column in a result set SQLDescribeCol 函数SQLDescribeCol Function
提取数据块或滚动结果集Fetching a block of data or scrolling through a result set SQLFetchScroll 函数SQLFetchScroll Function
提取多行数据Fetching multiple rows of data SQLFetch 函数SQLFetch Function
释放语句上的列缓冲区Releasing column buffers on the statement SQLFreeStmt 函数SQLFreeStmt Function
提取部分或全部数据列Fetching part or all of a column of data SQLGetData 函数SQLGetData Function
返回结果集列的数目Returning the number of result set columns SQLNumResultCols 函数SQLNumResultCols Function

另请参阅See Also

ODBC API 参考 ODBC API Reference
ODBC 头文件ODBC Header Files