SQLGetData 函数
一致性
引入的版本:ODBC 1.0 标准符合性:ISO 92
摘要
SQLGetData 检索结果集中单个列的数据,或在 SQLParamData 返回SQL_PARAM_DATA_AVAILABLE后检索单个参数的数据。 可以多次调用它来检索部件中的可变长度数据。
语法
SQLRETURN SQLGetData(
SQLHSTMT StatementHandle,
SQLUSMALLINT Col_or_Param_Num,
SQLSMALLINT TargetType,
SQLPOINTER TargetValuePtr,
SQLLEN BufferLength,
SQLLEN * StrLen_or_IndPtr);
参数
StatementHandle
[输入]语句句柄。
Col_or_Param_Num
[输入]对于检索列数据,它是要为其返回数据的列的编号。 结果集列以从 1 开始的递增列顺序进行编号。 书签列为第 0 列;仅当启用书签时,才能指定此项。
对于检索参数数据,它是参数的序号,从 1 开始。
TargetType
[输入]*TargetValuePtr 缓冲区的 C 数据类型的类型标识符。 有关有效 C 数据类型和类型标识符的列表,请参阅附录 D:数据类型中的 C 数据类型部分。
如果 TargetType SQL_ARD_TYPE,驱动程序将使用 ARD 的 SQL_DESC_CONCISE_TYPE 字段中指定的类型标识符。 如果 TargetType SQL_APD_TYPE, SQLGetData 将使用 SQLBindParameter 中指定的同一 C 数据类型。 否则, SQLGetData 中指定的 C 数据类型将替代 SQLBindParameter 中指定的 C 数据类型。 如果SQL_C_DEFAULT,驱动程序将根据源的 SQL 数据类型选择默认的 C 数据类型。
还可以指定扩展 C 数据类型。 有关详细信息,请参阅 ODBC 中的 C 数据类型。
TargetValuePtr
[输出]指向要在其中返回数据的缓冲区的指针。
TargetValuePtr 不能为 NULL。
BufferLength
[输入]*TargetValuePtr 缓冲区的长度(以字节为单位)。
驱动程序使用 BufferLength 避免在返回可变长度数据(如字符或二进制数据)时写入 *TargetValuePtr 缓冲区的末尾。 请注意,驱动程序在将字符数据返回到 *TargetValuePtr 时对 null 终止字符进行计数。 *因此,TargetValuePtr 必须包含 null 终止字符的空间,否则驱动程序将截断数据。
当驱动程序返回固定长度的数据(如整数或日期结构)时,驱动程序将忽略 BufferLength 并假定缓冲区足够大,足以保存数据。 因此,应用程序必须为固定长度的数据分配足够大的缓冲区,否则驱动程序将写入缓冲区末尾。
当 BufferLength 小于 0 时,SQLGetData 返回 SQLSTATE HY090 (无效的字符串或缓冲区长度) ,但 BufferLength 为 0 时则不返回。
StrLen_or_IndPtr
[输出]指向要返回长度或指示器值的缓冲区的指针。 如果这是 null 指针,则不返回长度或指示器值。 如果提取的数据为 NULL,则返回错误。
SQLGetData 可以在长度/指示器缓冲区中返回以下值:
可返回的数据的长度
SQL_NO_TOTAL
SQL_NULL_DATA
有关详细信息,请参阅本主题中的 使用长度/指示器值 和“注释”。
返回
SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_NO_DATA、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。
诊断
当 SQLGetData 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过调用 SQLGetDiagRec 并使用 handleType SQL_HANDLE_STMT 和 Handle of StatementHandle 来获取关联的 SQLSTATE 值。 下表列出了 SQLGetData 通常返回的 SQLSTATE 值,并说明了此函数上下文中的每个值:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATE 说明之前。 与每个 SQLSTATE 值关联的返回代码SQL_ERROR,除非另有说明。
SQLSTATE | 错误 | 说明 |
---|---|---|
01000 | 常规警告 | 特定于驱动程序的信息性消息。 (函数返回 SQL_SUCCESS_WITH_INFO.) |
01004 | 字符串数据,右截断 | 并非所有指定列的数据 (Col_or_Param_Num)都可以在对 函数的单个调用中检索。 在 *StrLen_or_IndPtr 中返回当前调用 SQLGetData 之前,SQL_NO_TOTAL或指定列中剩余的数据长度。 (函数返回 SQL_SUCCESS_WITH_INFO.) 有关对单个列使用 对 SQLGetData 的多次调用的详细信息,请参阅“注释”。 |
01S07 | 小数截断 | 为一列或多列返回的数据被截断。 对于数值数据类型,数字的小数部分被截断。 对于包含时间分量的时间、时间戳和间隔数据类型,时间的小数部分被截断。 (函数返回 SQL_SUCCESS_WITH_INFO.) |
07006 | 受限数据类型属性冲突 | 不能将结果集中列的数据值转换为由参数 TargetType 指定的 C 数据类型。 |
07009 | 描述符索引无效 | 为参数 Col_or_Param_Num 指定的值为 0,SQL_ATTR_USE_BOOKMARKS 语句属性设置为 SQL_UB_OFF。 为参数 指定的值Col_or_Param_Num 大于结果集中的列数。 Col_or_Param_Num值不等于可用参数的序号。 (DM) 指定列已绑定。 此说明不适用于在 SQLGetInfo 中返回 SQL_GETDATA_EXTENSIONS 选项的SQL_GD_BOUND位掩码的驱动程序。 (DM) 指定列的数目小于或等于最高绑定列的数目。 此说明不适用于在 SQLGetInfo 中返回SQL_GETDATA_EXTENSIONS选项的SQL_GD_ANY_COLUMN位掩码的驱动程序。 (DM) 应用程序已为当前行调用 SQLGetData ;当前调用中指定的列数小于在前面调用中指定的列数;驱动程序不会返回 SQLGetInfo 中SQL_GETDATA_EXTENSIONS选项的SQL_GD_ANY_ORDER位掩码。 (DM) TargetType 参数已SQL_ARD_TYPE,并且 ARD 中的 Col_or_Param_Num 描述符记录未通过一致性检查。 (DM) TargetType 参数已SQL_ARD_TYPE,并且 ARD 的 SQL_DESC_COUNT 字段中的值小于 Col_or_Param_Num 参数。 |
08S01 | 通信链接失败 | 在函数完成处理之前,驱动程序与所连接的数据源之间的通信链接失败。 |
22002 | 需要指示器变量,但未提供 | StrLen_or_IndPtr 为 null 指针,已检索 NULL 数据。 |
22003 | 数值范围外 | 以数字或字符串) 的形式返回列的数值 (会导致整个 (而不是数字的) 部分被截断。 有关详细信息,请参阅 附录 D:数据类型。 |
22007 | 日期/时间格式无效 | 结果集中的字符列绑定到 C 日期、时间或时间戳结构,列中的值分别为无效的日期、时间或时间戳。 有关详细信息,请参阅 附录 D:数据类型。 |
22012 | 被零除 | 返回了算术表达式中导致除以零的值。 |
22015 | 间隔字段溢出 | 从确切的数字或间隔 SQL 类型分配给间隔 C 类型会导致前导字段中的重要数字丢失。 将数据返回到间隔 C 类型时,间隔 C 类型中没有 SQL 类型的值表示形式。 |
22018 | 强制转换规范的字符值无效 | 结果集中的字符列已返回到字符 C 缓冲区,并且该列包含缓冲区的字符集中没有表示形式的字符。 C 类型是精确或近似数值、日期时间或间隔数据类型;列的 SQL 类型是字符数据类型;列中的值不是绑定 C 类型的有效文本。 |
24000 | 游标状态无效 | (DM) 调用函数时,未首先调用 SQLFetch 或 SQLFetchScroll 将光标置于所需数据行上。 (DM) StatementHandle 处于执行状态,但没有结果集与 StatementHandle 关联。 在 StatementHandle 上打开了游标,并且已调用 SQLFetch 或 SQLFetchScroll,但游标位于结果集开始之前或结果集末尾之后。 |
HY000 | 常规错误 | 发生错误,其中没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 SQLGetDiagRec 在 MessageText 缓冲区中返回的错误消息描述了错误及其原因。 |
HY001 | 内存分配错误 | 驱动程序无法分配支持执行或完成函数所需的内存。 |
HY003 | 程序类型范围外 | (DM) 参数 TargetType 不是有效的数据类型,SQL_C_DEFAULT,在检索列数据) 时SQL_ARD_TYPE (;在检索参数数据) 时SQL_APD_TYPE (。 (DM) 参数 Col_or_Param_Num 为 0,并且未SQL_C_BOOKMARK固定长度书签的参数 TargetType 或SQL_C_VARBOOKMARK可变长度书签。 |
HY008 | 操作已取消 | 已为 StatementHandle 启用异步处理。 调用了函数,在它完成执行之前,在 StatementHandle 上调用了 SQLCancel 或 SQLCancelHandle,然后在 StatementHandle 上再次调用该函数。 调用了函数,在它完成执行之前, SqlCancel 或 SQLCancelHandle 在 StatementHandle 上从多线程应用程序中的不同线程调用,然后在 StatementHandle 上再次调用该函数。 |
HY009 | null 指针的使用无效 | (DM) 参数 TargetValuePtr 为 null 指针。 |
HY010 | 函数序列错误 | (DM) 指定的 StatementHandle 未处于执行状态。 该函数是在未首先调用 SQLExecDirect、 SQLExecute 或目录函数的情况下调用的。 (DM) 为与 StatementHandle 关联的连接句柄调用了异步执行的函数。 调用 SQLGetData 函数时,此异步函数仍在执行。 (DM) 为 StatementHandle 调用了异步执行的函数, (不是此函数) ,在调用此函数时仍在执行。 (DM) SQLExecute、 SQLExecDirect、 SQLBulkOperations 或 SQLSetPos 已为 StatementHandle 调用,并返回SQL_NEED_DATA。 在针对所有数据执行参数或列发送数据之前调用了此函数。 (DM) StatementHandle 处于执行状态,但没有结果集与 StatementHandle 关联。 对 SQLExeceute、 SQLExecDirect 或 SQLMoreResults 的 调用返回SQL_PARAM_DATA_AVAILABLE,但调用了 SQLGetData ,而不是 SQLParamData。 |
HY013 | 内存管理错误 | 无法处理函数调用,因为无法访问基础内存对象,可能是由于内存不足。 |
HY090 | 无效的字符串或缓冲区长度 | (DM) 为参数 BufferLength 指定的值小于 0。 为 BufferLength 参数指定的值小于 4, Col_or_Param_Num 参数设置为 0,驱动程序是 ODBC 2*.x* 驱动程序。 |
HY109 | 游标位置无效 | 游标由 SQLSetPos、SQLFetch、SQLFetchScroll 或 SQLBulkOperations) (定位在已删除或无法提取的行上。 游标是仅向前游标,行集大小大于 1。 |
HY117 | 由于事务状态未知,连接已暂停。 仅允许断开连接和只读函数。 | (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数。 |
HYC00 | 未实现可选功能 | 驱动程序或数据源不支持在 SQLFetchScroll 中使用多行的 SQLGetData。 此说明不适用于在 SQLGetInfo 中返回 SQL_GETDATA_EXTENSIONS 选项的SQL_GD_BLOCK位掩码的驱动程序。 驱动程序或数据源不支持 TargetType 参数与相应列的 SQL 数据类型的组合指定的转换。 仅当列的 SQL 数据类型映射到特定于驱动程序的 SQL 数据类型时,此错误才适用。 驱动程序仅支持 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 的 驱动程序不支持 函数。 |
IM017 | 在异步通知模式下禁用轮询 | 每当使用通知模型时,将禁用轮询。 |
IM018 | 尚未调用 SQLCompleteAsync 来完成此句柄上的上一个异步操作。 | 如果对句柄的上一个函数调用返回SQL_STILL_EXECUTING并且启用了通知模式,则必须在句柄上调用 SQLCompleteAsync 以执行后期处理并完成操作。 |
注释
SQLGetData 返回指定列中的数据。 只有在 SQLFetch、SQLFetchScroll 或 SQLExtendedFetch 从结果集中提取一行或多行之后,才能调用 SQLGetData。 如果由于应用程序) 的限制,长度可变的数据太大,无法在对 SQLGetData (的单个调用中返回, SQLGetData 可以分部分检索它。 可以绑定行中的某些列,并为其他列调用 SQLGetData ,尽管这受到一些限制。 有关详细信息,请参阅 获取长数据。
有关将 SQLGetData 与流式输出参数配合使用的信息,请参阅 使用 SQLGetData 检索输出参数。
使用 SQLGetData
如果驱动程序不支持 SQLGetData 扩展,则函数只能返回数字大于最后一个绑定列的未绑定列的数据。 此外,在一行数据中,每次调用 SQLGetData 时Col_or_Param_Num参数的值必须大于或等于上一次调用中Col_or_Param_Num的值;也就是说,必须按增加列号顺序检索数据。 最后,如果不支持任何扩展,则如果行集大小大于 1,则无法调用 SQLGetData 。
驱动程序可以放宽其中的任何限制。 为了确定驱动程序放宽哪些限制,应用程序使用以下任一SQL_GETDATA_EXTENSIONS选项调用 SQLGetInfo :
SQL_GD_OUTPUT_PARAMS = SQLGetData 可以调用以返回输出参数值。 有关详细信息,请参阅 使用 SQLGetData 检索输出参数。
SQL_GD_ANY_COLUMN。 如果返回此选项,则可以对任何未绑定列(包括最后一个绑定列之前的列)调用 SQLGetData 。
SQL_GD_ANY_ORDER。 如果返回此选项,则可以按任意顺序为未绑定列调用 SQLGetData 。
SQL_GD_BLOCK。 如果 SQLGetInfo 为 SQL_GETDATA_EXTENSIONS InfoType 返回此选项,则当行集大小大于 1 时,驱动程序支持调用 SQLGetData,并且应用程序可以使用 SQL_POSITION 选项调用 SQLSetPos,以便在调用 SQLGetData 之前将光标置于正确的行上。
SQL_GD_BOUND。 如果返回此选项,则可以为绑定列和未绑定列调用 SQLGetData 。
这些限制有两个例外,以及驾驶员放宽限制的能力。 首先,当行集大小大于 1 时,绝不应为仅进游标调用 SQLGetData 。 其次,如果驱动程序支持书签,它必须始终支持为列 0 调用 SQLGetData 的功能,即使它不允许应用程序在最后一个绑定列之前为其他列调用 SQLGetData 。 (当应用程序使用 ODBC 2*.x* 驱动程序时, 调用 SQLFetch 后,当调用Col_or_Param_Num等于 0 时,SQLGetData 将成功返回书签,因为 SQLFetch 由 ODBC 3*.x* 驱动程序管理器映射到 SQLExtendedFetch,且 SQL_FETCH_NEXT Col_or_Param_Num为 0 的SQLGetData 由 ODBC 3*.x* 驱动程序管理器映射到 SQLGetStmtOptionSQL_GET_BOOKMARK.) 的 fOption
SQLGetData 不能用于检索刚刚通过使用 SQL_ADD 选项调用 SQLBulkOperations 插入的行的书签,因为游标未定位在行上。 在使用 SQL_ADD 调用 SQLBulkOperation 之前,应用程序可以通过绑定列 0 来检索此类行的书签,在这种情况下 ,SQLBulkOperations 将返回绑定缓冲区中的书签。 然后,可以使用 SQL_FETCH_BOOKMARK 调用 SQLFetchScroll,以将游标重新定位到该行上。
如果 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 显式设置相应的描述符字段。 它可以将SQL_DESC_CONCISE_TYPE字段设置为SQL_C_NUMERIC,并使用 targetType 参数SQL_ARD_TYPE调用 SQLGetData,这将导致使用描述符字段中的精度和小数位数值。
注意
在 ODBC 2*.x* 中,应用程序将 TargetType 设置为 SQL_C_DATE、SQL_C_TIME 或 SQL_C_TIMESTAMP,以指示 *TargetValuePtr 是日期、时间或时间戳结构。 在 ODBC 3*.x* 中,应用程序将 TargetType 设置为 SQL_C_TYPE_DATE、SQL_C_TYPE_TIME 或 SQL_C_TYPE_TIMESTAMP。 驱动程序管理器根据需要根据应用程序和驱动程序版本进行适当的映射。
检索部件中的Variable-Length数据
SQLGetData 可用于从包含可变长度数据的列中检索数据(即,当列的 SQL 数据类型的标识符为SQL_CHAR、SQL_VARCHAR、SQL_LONGVARCHAR、SQL_WCHAR、SQL_WVARCHAR、SQL_WLONGVARCHAR、SQL_BINARY、SQL_VARBINARY、SQL_LONGVARBINARY或可变长度类型的特定于驱动程序的标识符时)。
若要从分部分的列中检索数据,应用程序会连续多次为同一列调用 SQLGetData 。 每次调用时, SQLGetData 都会返回数据的下一部分。 应用程序负责重新组合部分,并注意从字符数据的中间部分删除 null 终止字符。 如果要返回的数据更多,或者没有为终止字符分配足够的缓冲区, SQLGetData 将返回SQL_SUCCESS_WITH_INFO,SQLSTATE 01004 (数据截断) 。 当它返回数据的最后一部分时, SQLGetData 返回SQL_SUCCESS。 在最后一次从列检索数据的有效调用中,不能返回SQL_NO_TOTAL和零,因为应用程序随后无法知道应用程序缓冲区中有多少数据有效。 如果在此之后调用 SQLGetData ,它将返回SQL_NO_DATA。 有关详细信息,请参阅下一节“使用 SQLGetData 检索数据”。
SQLGetData 可以分部分返回长度可变的书签。 与其他数据一样,调用 SQLGetData 以在部件中返回可变长度书签将返回 SQLSTATE 01004 (String 数据,) 右截断,并在返回更多数据时SQL_SUCCESS_WITH_INFO。 这不同于通过调用 SQLFetch 或 SQLFetchScroll 截断可变长度书签的情况,后者返回SQL_ERROR和 SQLSTATE 22001 (字符串数据,右截断) 。
SQLGetData 不能用于返回部件中的固定长度数据。 如果对包含固定长度数据的列在一行中多次调用 SQLGetData,则对于第一次之后的所有调用, SQLGetData 都会返回SQL_NO_DATA。
检索流式处理输出参数
如果驱动程序支持流式输出参数,应用程序可以使用小缓冲区多次调用 SQLGetData 来检索较大的参数值。 有关流输出参数的详细信息,请参阅 使用 SQLGetData 检索输出参数。
使用 SQLGetData 检索数据
若要返回指定列的数据, SQLGetData 将执行以下一系列步骤:
如果已返回列的所有数据,则返回SQL_NO_DATA。
如果数据为 NULL,则将 *StrLen_or_IndPtr 设置为SQL_NULL_DATA。 如果数据为 NULL 且 StrLen_or_IndPtr 为 null 指针, 则 SQLGetData 返回 SQLSTATE 22002 (Indicator 变量是必需的,但不) 提供。
如果列的数据不为 NULL, 则 SQLGetData 将继续执行步骤 3。
如果 SQL_ATTR_MAX_LENGTH 语句属性设置为非零值,如果列包含字符或二进制数据,并且之前未为该列调用 SQLGetData ,则数据将被截断为SQL_ATTR_MAX_LENGTH个字节。
注意
SQL_ATTR_MAX_LENGTH 语句属性旨在减少网络流量。 它通常由数据源实现,数据源在通过网络返回数据之前会截断数据。 无需驱动程序和数据源即可支持它。 因此,若要保证数据被截断为特定大小,应用程序应分配该大小的缓冲区,并在 BufferLength 参数中指定该大小。
将数据转换为 TargetType 中指定的类型。 数据具有该数据类型的默认精度和小数位数。 如果 TargetType SQL_ARD_TYPE,则使用 ARD SQL_DESC_CONCISE_TYPE 字段中的数据类型。 如果 TargetType SQL_ARD_TYPE,则会根据SQL_DESC_CONCISE_TYPE字段中的数据类型,在 ARD 的SQL_DESC_DATETIME_INTERVAL_PRECISION、SQL_DESC_PRECISION和SQL_DESC_SCALE字段中为数据提供精度和小数位数。 如果任何默认精度或小数位数都不适用,应用程序应通过调用 SQLSetDescField 或 SQLSetDescRec 显式设置相应的描述符字段。
如果数据已转换为可变长度数据类型(如字符或二进制), SQLGetData 会 检查数据的长度是否超过 BufferLength。 如果字符数据的长度 (包括 null 终止字符) 超过 BufferLength, SQLGetData 会将数据截断为 BufferLength ,减去 null 终止字符的长度。 然后,它以 null 终止数据。 如果二进制数据的长度超过数据缓冲区的长度, SQLGetData 会将其截断为 BufferLength 字节。
如果提供的数据缓冲区太小,无法容纳 null 终止字符, 则 SQLGetData 将返回SQL_SUCCESS_WITH_INFO和 SQLSTATE 01004。
SQLGetData 永远不会截断转换为固定长度数据类型的数据;它始终假定 *TargetValuePtr 的长度是数据类型的大小。
将转换后的 (并可能截断) 数据放在 *TargetValuePtr 中。 请注意, SQLGetData 无法按行返回数据。
将数据的长度置于 *StrLen_or_IndPtr 中。 如果 StrLen_or_IndPtr 为 null 指针, 则 SQLGetData 不返回长度。
对于字符或二进制数据,这是转换后和由于 BufferLength 而截断之前的数据长度。 如果驱动程序无法确定转换后的数据长度(有时与长数据的情况一样),它将返回SQL_SUCCESS_WITH_INFO并将长度设置为SQL_NO_TOTAL。 (上次调用 SQLGetData 必须始终返回数据的长度,而不是零或SQL_NO_TOTAL。) 如果由于 SQL_ATTR_MAX_LENGTH 语句属性而截断了数据,则此属性的值(而不是实际长度)将放置在 *StrLen_or_IndPtr 中。 这是因为此属性设计为在转换前截断服务器上的数据,因此驱动程序无法找出实际长度。 当针对同一列连续多次调用 SQLGetData 时,这是当前调用开始时可用数据的长度;也就是说,长度会随着每个后续调用而减少。
对于所有其他数据类型,这是转换后的数据长度;也就是说,它是数据转换为的类型的大小。
例如,如果在转换 (期间将数据截断而不丢失重要性, 当) 转换为整数 1 时,实数 1.234 将被截断,或者由于 BufferLength 太小 (将字符串“abcdef”放置在 4 字节缓冲区) 中, SQLGetData 返回 SQLSTATE 01004 (数据截断) 并SQL_SUCCESS_WITH_INFO。 如果由于 SQL_ATTR_MAX_LENGTH 语句属性而截断数据而不丢失重要性, 则 SQLGetData 将返回SQL_SUCCESS,并且不会返回 SQLSTATE 01004 (数据截断) 。
如果在绑定列) 上调用 SQLGetData ,则绑定数据缓冲区的内容 (;如果 SQLGetData 不返回SQL_SUCCESS或SQL_SUCCESS_WITH_INFO,则长度/指示器缓冲区未定义。
对 SQLGetData 的连续调用将从请求的最后一列检索数据;以前的偏移量变为无效。 例如,执行以下顺序时:
SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n)
第二次调用 SQLGetData (icol=n) 从 n 列的开头检索数据。 由于先前对列的 SQLGetData 调用而导致数据中的任何偏移量都不再有效。
描述符和 SQLGetData
SQLGetData 不直接与任何描述符字段交互。
如果 TargetType SQL_ARD_TYPE,则使用 ARD SQL_DESC_CONCISE_TYPE 字段中的数据类型。 如果 TargetType 为SQL_ARD_TYPE或SQL_C_DEFAULT,则会根据SQL_DESC_CONCISE_TYPE字段中的数据类型,在 ARD 的SQL_DESC_DATETIME_INTERVAL_PRECISION、SQL_DESC_PRECISION和SQL_DESC_SCALE字段中为数据提供精度和小数位数。
代码示例
在以下示例中,应用程序执行 SELECT 语句以返回按姓名、ID 和电话号码排序的客户 ID、姓名和电话号码的结果集。 对于每行数据,它调用 SQLFetch 将游标定位到下一行。 它调用 SQLGetData 来检索提取的数据;在调用 SQLGetData 时指定数据的缓冲区和返回的字节数。 最后,它打印每个员工的姓名、ID 和电话号码。
#define NAME_LEN 50
#define PHONE_LEN 50
SQLCHAR szName[NAME_LEN], szPhone[PHONE_LEN];
SQLINTEGER sCustID, cbName, cbAge, cbBirthday;
SQLRETURN retcode;
SQLHSTMT hstmt;
retcode = SQLExecDirect(hstmt,
"SELECT CUSTID, NAME, PHONE FROM CUSTOMERS ORDER BY 2, 1, 3",
SQL_NTS);
if (retcode == SQL_SUCCESS) {
while (TRUE) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
show_error();
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
/* Get data for columns 1, 2, and 3 */
SQLGetData(hstmt, 1, SQL_C_ULONG, &sCustID, 0, &cbCustID);
SQLGetData(hstmt, 2, SQL_C_CHAR, szName, NAME_LEN, &cbName);
SQLGetData(hstmt, 3, SQL_C_CHAR, szPhone, PHONE_LEN,
&cbPhone);
/* Print the row of data */
fprintf(out, "%-5d %-*s %*s", sCustID, NAME_LEN-1, szName,
PHONE_LEN-1, szPhone);
} else {
break;
}
}
}
相关函数
有关以下方面的信息 | 请参阅 |
---|---|
为结果集中的列分配存储 | SQLBindCol |
执行与块光标位置无关的批量操作 | SQLBulkOperations |
取消语句处理 | SQLCancel |
执行 SQL 语句 | SQLExecDirect |
执行准备好的 SQL 语句 | SQLExecute |
提取数据块或滚动浏览结果集 | SQLFetchScroll |
以仅向前方向提取单行数据或数据块 | SQLFetch |
在执行时发送参数数据 | SQLPutData |
定位游标、刷新行集中的数据,或者更新或删除行集中的数据 | SQLSetPos |