提取结果数据

ODBC 应用程序具有三个用于提取结果数据的选项。

第一个选项基于 SQLBindCol。 在提取结果集之前,应用程序使用 SQLBindCol 将结果集中的每一列绑定到程序变量。 绑定列后,每次应用程序调用 SQLFetch 或 SQLFetchScroll 时,驱动程序都会将当前行的数据传输到绑定到结果集列的变量中。 如果结果集列和程序变量具有不同的数据类型,则驱动程序将处理数据转换。 如果应用程序的SQL_ATTR_ROW_ARRAY_SIZE设置为大于 1,则可以将结果列绑定到变量数组,每次调用 SQLFetchScroll 时都会填充这些数组。

第二个选项基于 SQLGetData。 应用程序不使用 SQLBindCol 将结果集列绑定到程序变量。 每次调用 SQLFetch 后,应用程序都会为结果集中的每一列调用 SQLGetData 一次。 SQLGetData 指示驱动程序将数据从特定结果集列传输到特定程序变量,并指定列和变量的数据类型。 如果结果集列和程序变量具有不同的数据类型,则上述操作将允许驱动程序转换数据。 Textntextimage 列通常太大,无法容纳到程序变量中,但仍可使用 SQLGetData 进行检索。 如果结果列中 的文本ntext图像 数据大于程序变量, SQLGetData 将返回SQL_SUCCESS_WITH_INFO,SQLSTATE 01004 (字符串数据,) 右截断。 对 SQLGetData 的连续调用将返回 文本图像 数据的连续区块。 到达数据末尾时, SQLGetData 返回SQL_SUCCESS。 如果 SQL_ATTR_ROW_ARRAY_SIZE 大于 1,则每个提取都将返回一组行或行集。 在使用 SQLGetData 之前,必须先使用 SQLSetPos 将行集中的特定行指定为当前行。

第三个选项是混合使用 SQLBindColSQLGetData。 例如,应用程序可以绑定结果集的前十列,然后在每次提取时调用 SQLGetData 三次,以从三个未绑定的列中检索数据。 当结果集包含一个或多个 文本图像 列时,通常会使用此方法。

根据为结果集设置的游标选项,应用程序还可以使用 SQLFetchScroll 的滚动选项来滚动结果集。

过度使用 SQLBindCol 将结果集列绑定到程序变量的成本很高,因为 SQLBindCol 会导致 ODBC 驱动程序分配内存。 将结果列绑定到变量时,该绑定将一直有效,直到调用 SQLFreeHandle 来释放语句句柄,或者在 fOption 设置为 SQL_UNBIND 的情况下调用 SQLFreeStmt。 在该语句完成前绑定不自动撤消。

通过这一逻辑,您可以高效地处理使用不同参数多次执行同一 SELECT 语句的情况。 由于结果集保持相同的结构,因此可以绑定结果集一次,处理所有 SELECT 语句,然后在上次执行后将 fOption 设置为 SQL_UNBIND 调用 SQLFreeStmt。 如果不首先调用将 fOption 设置为 SQL_UNBIND 的 SQLFreeStmt 来释放任何以前的绑定,则不应调用 SQLBindCol 来绑定结果集中的列。

使用 SQLBindCol 时,可以执行行绑定或列绑定。 按行绑定比按列绑定稍快。

可以使用 SQLGetData 逐列检索数据,而不是使用 SQLBindCol 绑定结果集列。 如果结果集仅包含几行,则使用 SQLGetData 而不是 SQLBindCol 会更快;否则, SQLBindCol 会提供最佳性能。 如果不总是将数据放在同一组变量中,则应使用 SQLGetData ,而不是不断重新绑定。 只有在所有列都与 SQLBindCol 绑定后,才能对选择列表中的列使用 SQLGetData。 列还必须出现在已使用 SQLGetData 的任何列之后。

处理将数据移入或移出程序变量的 ODBC 函数(如 SQLGetDataSQLBindColSQLBindParameter)支持隐式数据类型转换。 例如,如果应用程序将某一整数列绑定到某一字符串程序变量,则驱动程序将会首先自动把数据从整数转换为字符,然后将其置于该程序变量中。

应用程序中的数据转换应尽可能少。 如果对应用程序执行的处理不要求数据转换,则应用程序应将列和参数绑定到同一数据类型的程序变量。 但是,如果数据必须从一种类型转换为另一种类型,让驱动程序执行转换比在应用程序中执行转换的效率更高。 SQL Server Native Client ODBC 驱动程序通常只是将数据直接从网络缓冲区传输到应用程序的变量。 请求驱动程序执行数据转换将强制驱动程序把数据存入缓冲区并使用 CPU 周期来转换数据。

程序变量应足够大,以便保存从列传输的数据, 文本ntext图像 数据除外。 如果某一应用程序尝试检索结果集数据,而放置这些数据的变量太小以致无法保存数据,则驱动程序将生成一个警告。 这强制驱动程序为消息分配内存,并且驱动程序和应用程序都必须将 CPU 周期花在处理消息和执行错误处理上。 应用程序应或者分配在大小上足以存放检索的数据的变量,或者在选择列表中使用 SUBSTRING 函数减小结果集中列的大小。

在使用 SQL_C_DEFAULT 指定 C 变量的类型时必须小心。 SQL_C_DEFAULT 指定 C 变量的类型与列或参数的 SQL 数据类型匹配。 如果为 ntextncharnvarchar 列指定了 SQL_C_DEFAULT,则 Unicode 数据将返回到应用程序。 如果尚未对应用程序进行编码以处理 Unicode 数据,则上述操作可能导致不同的问题。 uniqueidentifier (SQL_GUID) 数据类型可能会出现相同类型的问题。

textntextimage 数据通常太大,无法容纳到单个程序变量中,并且通常使用 SQLGetData 而不是 SQLBindCol 进行处理。 使用服务器游标时,SQL Server Native Client ODBC 驱动程序经过优化,以便在提取行时不传输未绑定文本ntextimage 列的数据。 在应用程序为列发出 SQLGetData 之前,实际上不会从服务器检索文本ntext图像数据。

此优化可以应用于应用程序,以便在用户上下滚动光标时不显示 文本ntext图像 数据。 用户选择行后,应用程序可以调用 SQLGetData 来检索 文本ntext图像 数据。 这将保存用户未选择的任何行 的文本ntext图像 数据的传输,并可以保存大量数据的传输。

另请参阅

处理结果 (ODBC)