处理生成消息的语句

Transact-SQL SET 语句选项 STATISTICS TIME 和 STATISTICS IO 用于获取有助于诊断长时间运行的查询的信息。SQL Server 的早期版本还支持用于分析查询计划的 SHOWPLAN 选项。ODBC 应用程序可通过执行以下语句设置这些选项:

SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS);
SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90
);
SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS);

当 SET STATISTICS TIME 或 SET SHOWPLAN 为 ON 时,SQLExecuteSQLExecDirect 返回 SQL_SUCCESS_WITH_INFO,此时,应用程序可以通过调用 SQLGetDiagRec 来检索 SHOWPLAN 或 STATISTICS TIME 输出,直到其返回 SQL_NO_DATA 为止。SHOWPLAN 数据的每一行均按以下格式返回:

szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server] 
              Table Scan"

SQL Server 7.0 版将 SHOWPLAN 选项替换为 SHOWPLAN_ALL 和 SHOWPLAN_TEXT,后两个选项均将输出作为结果集(而不是一组消息)返回。

STATISTICS TIME 的每一行均按以下格式返回:

szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
   SQL Server Parse and Compile Time: cpu time = 0 ms."

在到达结果集的末尾之前,SET STATISTICS IO 的输出不可用。为获取 STATISTICS IO 输出,应用程序将在 SQLFetchSQLFetchScroll返回 SQL_NO_DATA 时调用 SQLGetDiagRec。STATISTICS IO 的输出按以下格式返回:

szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
   Table: testshow  scan count 1,  logical reads: 1,
   physical reads: 0."

使用 DBCC 语句

DBCC 语句将其数据作为消息(而不是结果集)返回。SQLExecDirectSQLExecute 返回 SQL_SUCCESS_WITH_INFO,并且应用程序通过调用 SQLGetDiagRec 来检索输出,直到它返回 SQL_NO_DATA 为止。

例如,下面的语句返回 SQL_SUCCESS_WITH_INFO:

SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);

SQLGetDiagRec 的调用将返回:

szSqlState = "01000", *pfNativeError = 2536,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
   Checking authors"
szSqlState = "01000", *pfNativeError = 2579,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
   The total number of data pages in this table is 1."
szSqlState = "01000", *pfNativeError = 7929,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
   Table has 23 data rows."
szSqlState = "01000", *pfNativeError = 2528
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
   DBCC execution completed. If DBCC printed error messages,
   see your System Administrator."

使用 PRINT 和 RAISERROR 语句

Transact-SQL PRINT 和 RAISERROR 语句也通过调用 SQLGetDiagRec 来返回数据。PRINT 语句使 SQL 语句执行后返回 SQL_SUCCESS_WITH_INFO,并且对 SQLGetDiagRec 的后续调用返回值为 01000 的 SQLState。严重性为 10 或更低的 RAISERROR 在行为上与 PRINT 相同。严重性为 11 或更高的 RAISERROR 导致执行后返回 SQL_ERROR,并且对 SQLGetDiagRec 的后续调用返回 SQLState 42000。例如,下面的语句返回 SQL_SUCCESS_WITH_INFO:

SQLExecDirect (hstmt, "PRINT  'Some message' ", SQL_NTS);

调用 SQLGetDiagRec 后将返回:

szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
   Some message"

下面的语句返回 SQL_SUCCESS_WITH_INFO:

SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
   SQL_NTS)

调用 SQLGetDiagRec 后将返回:

szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
   Sample error 1."

下面的语句返回 SQL_ERROR:

SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)

调用 SQLGetDiagRec 后将返回:

szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
   Sample error 2."

当结果集包含 PRINT 或 RAISERROR 语句的输出时,调用 SQLGetDiagRec 的时间安排非常重要。在执行接收 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO 的语句之后,必须立即调用 SQLGetDiagRec 来检索 PRINT 或 RAISERROR 输出。当仅执行一个 SQL 语句时(如上述示例中所示),这非常简单。在这些情况下,调用 SQLExecDirectSQLExecute 后将返回 SQL_ERROR 或 SQL_SUCCESS_WITH_INFO,随后可以调用 SQLGetDiagRec。当编写循环代码以处理一批 SQL 语句的输出或者当执行 SQL Server 存储过程时,这要复杂一些。

在这种情况下,SQL Server 为在批处理或存储过程中执行的每个 SELECT 语句返回一个结果集。如果批处理或过程包含 PRINT 或 RAISERROR 语句,它们的输出将与 SELECT 语句结果集交叉。如果该批处理或过程中的第一条语句为 PRINT 或 RAISERROR,SQLExecuteSQLExecDirect 将返回 SQL_SUCCESS_WITH_INFO 或 SQL_ERROR,并且应用程序需要调用 SQLGetDiagRec 来检索 PRINT 或 RAISERROR 信息,直到其返回 SQL_NO_DATA 为止。

如果 PRINT 或 RAISERROR 语句在 SQL 语句(如 SELECT 语句)之后,PRINT 或 RAISERROR 信息将在 SQLMoreResults 位于包含错误的结果集中时返回。SQLMoreResults 根据消息的严重性来返回 SQL_SUCCESS_WITH_INFO 或 SQL_ERROR。通过调用 SQLGetDiagRec 来检索消息,直到其返回 SQL_NO_DATA 为止。

请参阅

概念