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,但当 BufferLength 为 0 时,SQLGetData 返回 SQLSTATE HY090 (字符串或缓冲区长度无效)。

StrLen_or_IndPtr
[输出]指向要返回长度或指示器值的缓冲区的指针。 如果这是空指针,则不返回长度或指示器值。 当提取的数据为 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时,可以通过使用 handleType of SQL_HANDLE_STMT 和 StatementHandle 句柄调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLGetData 通常返回的 SQLSTATE 值,并解释此函数上下文中的每个值;表示法“(DM)”位于驱动程序管理器返回的 SQLSTATE 的说明之前。 除非另有说明,否则与每个 SQLSTATE 值关联的返回代码SQL_ERROR。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回SQL_SUCCESS_WITH_INFO。)
01004 字符串数据,右截断 并非所有指定列的所有数据( Col_or_Param_Num)都可以在对函数的单个调用中检索。 在对 SQLGetData 的当前调用之前,SQL_NO_TOTAL或指定列中剩余的数据长度在 *StrLen_or_IndPtr 中返回。 (函数返回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) 指定的列已绑定。 此说明不适用于返回 SQLGetInfoSQL_GETDATA_EXTENSIONS选项SQL_GD_BOUND位掩码的驱动程序。

(DM) 指定列的数目小于或等于最大绑定列的数目。 此说明不适用于在 SQLGetInfo返回SQL_GETDATA_EXTENSIONS选项的SQL_GD_ANY_COLUMN位掩码的驱动程序。

(DM) 应用程序已为当前行调用了 SQLGetData;当前调用中指定的列数小于上述调用中指定的列数;驱动程序不会返回 SQLGetInfoSQL_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 数据。
22003 数值范围之外 返回列的数值(作为数字或字符串)将导致截断数字的整个部分(而不是小数部分)。

有关详细信息,请参阅 附录 D:数据类型
22007 日期/时间格式无效 结果集中的字符列绑定到 C 日期、时间或时间戳结构,并且列中的值分别为无效的日期、时间或时间戳。 有关详细信息,请参阅 附录 D:数据类型
22012 被零除 从算术表达式返回一个值,该表达式返回除以零。
22015 间隔字段溢出 从确切的数字或间隔 SQL 类型分配给间隔 C 类型会导致前导字段中的有效数字丢失。

将数据返回到间隔 C 类型时,间隔 C 类型中没有 SQL 类型的值表示形式。
22018 强制转换规范的字符值无效 结果集中的字符列返回到字符 C 缓冲区,该列包含一个字符,该字符集在缓冲区的字符集中没有表示形式。

C 类型是精确或近似数字、日期/时间或间隔数据类型;列的 SQL 类型是字符数据类型;列中的值不是绑定 C 类型的有效文本。
24000 游标状态无效 (DM) 调用该函数时不首先调用 SQLFetchSQLFetchScroll ,以便将光标置于所需的数据行上。

(DM) StatementHandle 处于执行状态,但没有结果集与 StatementHandle 相关联。

已调用 StatementHandle 和 SQLFetch 或 SQLFetchScroll 上的游标,但游标位于结果集的开头或结果集末尾之后。
HY000 常规错误 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY003 程序类型范围不足 (DM) 参数 TargetType 不是有效的数据类型、SQL_C_DEFAULT、SQL_ARD_TYPE(检索列数据时),或SQL_APD_TYPE(检索参数数据时)。

(DM) 参数Col_or_Param_Num为 0,而 targetType 的参数不是固定长度书签的SQL_C_BOOKMARK,也不是可变长度书签的SQL_C_VARBOOKMARK。
HY008 操作已取消 StatementHandle 启用了异步处理。 调用了该函数,在完成执行之前,对 StatementHandle 调用 SQLCancel 或 SQLCancelHandle,然后在 StatementHandle再次调用该函数。

调用了该函数,在完成执行之前,SQLCancel 或 SQLCancelHandle 从多线程应用程序中的不同线程调用 StatementHandle,然后在 StatementHandle再次调用该函数。
HY009 无效使用 null 指针 (DM) 参数 TargetValuePtr 为空指针。
HY010 函数序列错误 (DM) 指定的 StatementHandle 未处于执行状态。 在未首先调用 SQLExecDirectSQLExecute 或目录函数的情况下调用该函数。

(DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 调用 SQLGetData 函数时,此异步函数仍在执行。

(DM) 为 StatementHandle 调用异步执行函数(而不是此函数),并在调用此函数时仍在执行。

(DM) 为 StatementHandle 调用了 SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos,并返回了SQL_NEED_DATA。 在为所有数据执行参数或列发送数据之前调用此函数。

(DM) StatementHandle 处于执行状态,但没有结果集与 StatementHandle 相关联。

对 SQLExeceute、SQLExecDirectSQLMoreResults 的调用SQL_PARAM_DATA_AVAILABLE返回,但调用了 SQLGetData,而不是 SQLParamData
HY013 内存管理错误 无法处理函数调用,因为基础内存对象无法访问,可能是因为内存条件低。
HY090 字符串或缓冲区长度无效 (DM) 为参数 BufferLength 指定的值小于 0。

为参数 BufferLength 指定的值小于 4,Col_or_Param_Num参数设置为 0,驱动程序为 ODBC 2*.x* 驱动程序。
HY109 光标位置无效 游标位于已删除或无法提取的行上(由 SQLSetPosSQLFetchSQLFetchScrollSQLBulkOperations) 定位。

游标是仅向前游标,行集大小大于 1。
HY117 连接因未知事务状态而挂起。 仅允许断开连接和只读函数。 (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数
HYC00 未实现可选功能 驱动程序或数据源不支持将 SQLGetData 与 SQLFetchScroll 中的多行一起使用。 此说明不适用于返回 SQLGetInfoSQL_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、SQLFetchScrollSQLExtendedFetch 从结果集中提取了一行或多行之后,才能调用 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 后,SQLGetData 会在调用 Col_or_Param_Num等于 0 时成功返回书签, 因为 SQLFetch 由 ODBC 3*.x* 驱动程序管理器映射到具有 fetchOrientation 的 SQLExtendedFetch,并且具有 SQL_FETCH_NEXT 0 Col_or_Param_Num的 SQLGetData 由 ODBC 3*.x* 驱动程序管理器映射到具有 fOption 的 fOption SQL_GET_BOOKMARK 的 SQLGetStmtOption

SQLGetData 不能用于通过调用具有 SQL_ADD 选项的 SQLBulkOperations 来检索刚插入的行的书签,因为游标未放置在行上。 应用程序可以通过绑定列 0 检索此类行的书签,然后再使用 SQL_ADD 调用 SQLBulkOperations ,在这种情况下 ,SQLBulkOperations 返回绑定缓冲区中的书签。 然后,可以使用SQL_FETCH_BOOKMARK调用 SQLFetchScroll 以重新定位该行上的游标。

如果 TargetType 参数是间隔数据类型,则分别在 ARD 的SQL_DESC_DATETIME_INTERVAL_PRECISION和SQL_DESC_PRECISION字段中设置的默认间隔前导精度(2)和默认间隔秒精度(6)。 如果 TargetType 参数是SQL_C_NUMERIC数据类型,则会对数据使用SQL_DESC_PRECISION和SQL_DESC_SCALE字段中设置的默认精度(驱动程序定义)和默认刻度(0)。 如果任何默认精度或小数位数不合适,应用程序应通过调用 SQLSetDescFieldSQLSetDescRec 显式设置相应的描述符字段。 它可以将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。 驱动程序管理器根据需要根据应用程序和驱动程序版本进行适当的映射。

检索部件中的可变长度数据

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(字符串数据,右截断),并在返回更多数据时SQL_SUCCESS_WITH_INFO。 这与调用 SQLFetch 或 SQLFetchScroll 截断可变长度书签的情况不同,后者返回 SQL_ERROR 和 SQLSTATE 22001(字符串数据,右截断)。

SQLGetData 不能用于返回部分的固定长度数据。 如果 SQLGetData 在一行中为包含固定长度数据的列调用多个时间,则它为第一次之后的所有调用返回SQL_NO_DATA。

检索流式输出参数

如果驱动程序支持流式输出参数,应用程序可以多次调用 带小缓冲区的 SQLGetData 来检索大型参数值。 有关流式输出参数的详细信息,请参阅 使用 SQLGetData 检索输出参数。

使用 SQLGetData 检索数据

若要返回指定列的数据, SQLGetData 将执行以下步骤序列:

  1. 如果已返回列的所有数据,则返回SQL_NO_DATA。

  2. 如果数据为 NULL,则将 *StrLen_or_IndPtr 设置为SQL_NULL_DATA。 如果数据为 NULL 且 StrLen_or_IndPtr 为空指针, 则 SQLGetData 返回 SQLSTATE 22002(需要指示器变量但未提供)。

    如果列的数据不为 NULL, 则 SQLGetData 将继续执行步骤 3。

  3. 如果 SQL_ATTR_MAX_LENGTH 语句属性设置为非零值,如果列包含字符或二进制数据,并且以前 尚未为该列调用 SQLGetData ,则数据将被截断为SQL_ATTR_MAX_LENGTH字节。

    注意

    SQL_ATTR_MAX_LENGTH语句属性旨在减少网络流量。 它通常由数据源实现,该数据源在通过网络返回数据之前会截断数据。 不支持驱动程序和数据源。 因此,为了保证数据被截断为特定大小,应用程序应分配该大小的缓冲区,并在 BufferLength 参数中指定大小。

  4. 将数据转换为 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字段的精度和小数位数。 如果任何默认精度或小数位数不合适,应用程序应通过调用 SQLSetDescFieldSQLSetDescRec 显式设置相应的描述符字段。

  5. 如果数据转换为可变长度数据类型(如字符或二进制数据), SQLGetData 将检查数据的长度是否超过 BufferLength。 如果字符数据的长度(包括 null 终止字符)超过 BufferLength,则 SQLGetData 会将数据截断为 BufferLength,减少 null 终止字符的长度。 然后,它会以 null 结尾数据。 如果二进制数据的长度超过数据缓冲区的长度, SQLGetData 会将它截断为 BufferLength 字节。

    如果提供的数据缓冲区太小,无法容纳 null 终止字符, SQLGetData 将返回SQL_SUCCESS_WITH_INFO和 SQLSTATE 01004。

    SQLGetData 永远不会截断转换为固定长度数据类型的数据;它始终假定 *TargetValuePtr 的长度是数据类型的大小。

  6. 在 *TargetValuePtr 中放置转换后的(可能截断)数据。 请注意, SQLGetData 无法从行外返回数据。

  7. 将数据的长度置于 *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,这是当前调用开始时可用的数据的长度;也就是说,每次后续调用的长度都会减少。

    • 对于所有其他数据类型,这是转换后数据的长度;也就是说,它是数据转换为的类型的大小。

  8. 如果在转换期间不丢失重要性数据(例如,在转换为整数 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

另请参阅

ODBC API 参考
ODBC 头文件
使用 SQLGetData 检索输出参数