处理结果 (ODBC)

应用程序提交 SQL 语句之后,SQL Server 会将得到的任何数据作为一个或多个结果集返回。结果集是一组与查询条件匹配的行和列。SELECT 语句、目录函数和某些存储过程可产生以表格格式供应用程序使用的结果集。如果执行的 SQL 语句为存储过程、包含多个命令的批处理或包含关键字(例如 COMPUTE 或 COMPUTE BY)的 SELECT 语句,则会有多个要处理的结果集。

ODBC 目录函数也可以检索数据。例如,SQLColumns 用于检索有关数据源中的列的数据。这些结果集可以包含零行或更多行。

其他 SQL 语句(如 GRANT 或 REVOKE)不返回结果集。对于这些语句,SQLExecuteSQLExecDirect 的返回代码通常是表示语句成功执行的唯一内容。

每个 INSERT、UPDATE 和 DELETE 语句均返回一个仅包含受修改影响的行数的结果集。应用程序调用 SQLRowCount 时,将提供该计数。ODBC 3.x 应用程序必须调用 SQLRowCount 来检索结果集,或调用 SQLMoreResults 来取消结果集。当应用程序执行包含多个 INSERT、UPDATE 或 DELETE 语句的批处理或存储过程时,必须使用 SQLRowCount 来处理每个修改语句产生的结果集,或使用 SQLMoreResults 取消这些结果集。通过在批处理或存储过程中包含 SET NOCOUNT ON 语句,可以取消这些计数。

Transact-SQL 包括 SET NOCOUNT 语句。NOCOUNT 选项设置为 on 时,SQL Server 不返回受语句影响的行计数,并且 SQLRowCount 返回 0。SQL Server Native Client ODBC 驱动程序版本引入了特定于驱动程序的 SQLGetStmtAttr 选项 SQL_SOPT_SS_NOCOUNT_STATUS,用以报告 NOCOUNT 选项是 on 还是 off。无论何时,只要 SQLRowCount 返回 0,应用程序都应测试 SQL_SOPT_SS_NOCOUNT_STATUS。如果返回了 SQL_NC_ON,则 SQLRowCount 返回的 0 值仅表示 SQL Server 尚未返回行计数。如果返回了 SQL_NC_OFF,则表示 NOCOUNT 为 off,并且 SQLRowCount 返回的 0 值表示该语句未影响任何行。当 SQL_SOPT_SS_NOCOUNT_STATUS 为 SQL_NC_OFF 时,应用程序不应显示 SQLRowCount 的值。大型批处理或存储过程可能包含多个 SET NOCOUNT 语句,因此程序员不能假定 SQL_SOPT_SS_NOCOUNT_STATUS 保持不变。每次 SQLRowCount 返回 0 时,均应测试该选项。

有若干其他 Transact-SQL 语句在消息中而不是在结果集中返回它们的值。当 SQL Server Native Client ODBC 驱动程序收到这些消息时,它将返回 SQL_SUCCESS_WITH_INFO 以使应用程序了解到有信息性消息可用。然后,应用程序便可以调用 SQLGetDiagRec 来检索这些消息。以这种方式工作的 Transact-SQL 语句如下:

  • DBCC

  • SET SHOWPLAN(在早期版本的 SQL Server 中提供)

  • SET STATISTICS

  • PRINT

  • RAISERROR

对于严重性级别为 11 或更高的 RAISERROR,SQL Server Native Client ODBC 驱动程序将返回 SQL_ERROR。如果 RAISERROR 的严重性级别为 19 或更高,则连接也会断开。

为了处理 SQL 语句产生的结果集,应用程序会执行以下操作:

  • 确定结果集的特征。

  • 将列绑定到程序变量。

  • 检索单个值、整行值或多行值。

  • 进行测试以查看是否存在多个结果集,如果存在,则进行环回以确定新结果集的特征。

从数据源中检索行并将其返回给应用程序的过程称为提取。

检索 COMPUTE 和 COMPUTE BY 结果集

COMPUTE BY 子句在结果集内生成小计;COMPUTE 子句在结果集结尾生成总计。SQL Server Native Client ODBC 驱动程序通过为每个 SELECT 语句生成多个结果集,向执行调用的应用程序提供这些总计和小计。

下例使用 COMPUTE BY 生成小计并使用 COMPUTE 生成总计:

SELECT Title = CONVERT(char(20), title), type, price, advance
FROM Titles
WHERE ytd_sales IS NOT NULL
  AND type LIKE '%cook%'
ORDER BY type DESC
COMPUTE AVG(price), SUM(advance) BY type
COMPUTE SUM(price), SUM(advance)

这些语句对每种书类型的平均价格进行小计计算并计算每种书类型的预付款之和,然后计算价格和预付款数据的最终总和。驱动程序提供具有第一种书类型的书中行的第一个结果集。接着,它生成带有第一组书的 AVG(price) 和 SUM(advance) 的两个 COMPUTE BY 列的第二个结果集。然后,它生成下一组书的第三个结果集和带有该组的 COMPUTE BY 小计的第四个结果集。驱动程序交叉提供这些结果集,直到它生成带有 COMPUTE SUM(price), SUM(advance) 子句的总计的最终结果集为止。