ODBC 应用程序有三个选项用于提取结果数据。
第一个选项基于 SQLBindCol。 在提取结果集之前,应用程序使用 SQLBindCol 将结果集中的每个列绑定到程序变量。 绑定列后,驱动程序会在应用程序每次调用 SQLFetch 或 SQLFetchScroll 时,将当前行的数据传输到绑定到结果集列的变量中。 如果结果集列和程序变量具有不同的数据类型,驱动程序将处理数据转换。 如果应用程序SQL_ATTR_ROW_ARRAY_SIZE设置为大于 1,则可以将结果列绑定到变量数组,这些变量将在每次调用 SQLFetchScroll 时填充。
第二个选项基于 SQLGetData。 应用程序不使用 SQLBindCol 将结果集列绑定到程序变量。 每次调用 SQLFetch 后,应用程序都会针对结果集中的每一列调用 一次 SQLGetData 。 SQLGetData 指示驱动程序将数据从特定结果集列传输到特定程序变量,并指定列和变量的数据类型。 这允许驱动程序在结果列和程序变量具有不同的数据类型时转换数据。 文本、 ntext 和 图像 列通常太大,无法容纳到程序变量中,但仍可以使用 SQLGetData 进行检索。 如果结果列中 的文本、 ntext 或 图像 数据大于程序变量, SQLGetData 将返回 SQL_SUCCESS_WITH_INFO 和 SQLSTATE 01004(字符串数据,右截断)。 对 SQLGetData 的连续调用返回 文本 或 图像 数据的连续区块。 到达数据末尾时, SQLGetData 返回SQL_SUCCESS。 如果SQL_ATTR_ROW_ARRAY_SIZE大于 1,则每个提取将返回一组行或行集。 在使用 SQLGetData 之前,必须先使用 SQLSetPos 将行集中的特定行指定为当前行。
第三个选项是混合使用 SQLBindCol 和 SQLGetData。 例如,应用程序可以绑定结果集的前 10 列,然后在每次提取时调用 SQLGetData 三次,以从三个未绑定列检索数据。 这通常在结果集包含一个或多个 文本 或 图像 列时使用。
根据结果集设置的游标选项,应用程序还可以使用 SQLFetchScroll 的滚动选项在结果集周围滚动。
过度使用 SQLBindCol 将结果集列绑定到程序变量的成本很高,因为 SQLBindCol 会导致 ODBC 驱动程序分配内存。 将结果列绑定到变量时,该绑定将一直有效,直到调用 SQLFreeHandle 以释放语句句柄或将 fOption 设置为SQL_UNBIND调用 SQLFreeStmt。 当语句完成时,绑定不会自动撤消。
通过此逻辑,可以使用不同的参数多次有效地处理执行同一 SELECT 语句。 由于结果集保留相同的结构,因此可以绑定结果集一次,处理所有 SELECT 语句,然后在上次执行后调用 fOption 设置为SQL_UNBIND的 SQLFreeStmt。 不应调用 SQLBindCol 来绑定结果集中的列,而无需先调用 fOption 设置为 SQL_UNBIND 的 SQLFreeStmt 以释放任何以前的绑定。
使用 SQLBindCol 时,可以按行或按列绑定。 行式绑定比列式绑定要快一些。
可以使用 SQLGetData 逐列检索数据,而不是使用 SQLBindCol 绑定结果集列。 如果结果集仅包含几行,则使用 SQLGetData 而不是 SQLBindCol 速度更快;否则, SQLBindCol 可提供最佳性能。 如果不总是将数据放在同一组变量中,则应使用 SQLGetData 而不是不断重新绑定。 只有在所有列都与 SQLBindCol 绑定后,才能对选定列表中的列使用 SQLGetData。 列还必须显示在已使用 SQLGetData 的任何列之后。
处理将数据移入或移出程序变量(如 SQLGetData、 SQLBindCol 和 SQLBindParameter)的 ODBC 函数支持隐式数据类型转换。 例如,如果应用程序将整数列绑定到字符串程序变量,驱动程序会在将数据放入程序变量之前自动将数据从整数转换为字符。
应尽量减少应用程序中的数据转换。 除非应用程序完成的处理需要数据转换,否则应用程序应将列和参数绑定到相同数据类型的程序变量。 但是,如果数据必须从一种类型转换为另一种类型,则让驱动程序执行转换比在应用程序中执行转换更有效。 SQL Server Native Client ODBC 驱动程序通常只将数据直接从网络缓冲区传输到应用程序的变量。 请求驱动程序执行数据转换会强制驱动程序缓冲数据,并使用 CPU 周期转换数据。
程序变量应足够大,可以保存从列传输的数据,但 文本、 ntext 和 图像 数据除外。 如果应用程序尝试检索结果集数据并将其置于太小而无法保存的变量中,驱动程序将生成警告。 这强制驱动程序为消息分配内存,驱动程序和应用程序都需要花费 CPU 周期来处理消息并执行错误处理。 应用程序应分配足够大的变量来保存要检索的数据,或使用选择列表中的 SUBSTRING 函数来减小结果集中列的大小。
在使用SQL_C_DEFAULT指定 C 变量的类型时,必须小心。 SQL_C_DEFAULT指定 C 变量的类型与列或参数的 SQL 数据类型匹配。 如果为 ntext、 nchar 或 nvarchar 列指定了SQL_C_DEFAULT,则 Unicode 数据将返回到应用程序。 如果应用程序尚未编码以处理 Unicode 数据,则可能会导致各种问题。 uniqueidentifier (SQL_GUID) 数据类型可能出现相同的问题类型。
文本、 ntext 和 图像 数据通常太大,无法容纳到单个程序变量中,通常使用 SQLGetData 而不是 SQLBindCol 进行处理。 使用服务器游标时,SQL Server Native Client ODBC 驱动程序经过优化,以便在提取行时不传输未绑定 文本、 ntext 或 图像 列的数据。 在应用程序为列发出 SQLGetData 之前,实际上不会从服务器检索文本、ntext 或图像数据。
此优化可以应用于应用程序,以便在用户向上和向下滚动光标时不显示 任何文本、 ntext 或 图像 数据。 用户选择行后,应用程序可以调用 SQLGetData 来检索 文本、 ntext 或 图像 数据。 这会保存用户未选择的任何行 的文本、 ntext 或 图像 数据,并且可以保存大量数据的传输。