處理產生訊息的陳述式
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 時, SQLExecute 和 SQLExecDirect 會傳回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 輸出,應用程式會在SQLFetch 或 SQLFetchScroll傳回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 陳述式會傳回其資料做為訊息,而非結果集。 SQLExecDirect 或 SQLExecute 會傳回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 的時間非常重要。 呼叫 SQLGetDiagRec 以擷取 PRINT 或 RAISERROR 輸出必須緊接在接收SQL_ERROR或SQL_SUCCESS_WITH_INFO的語句之後。 僅執行單一 SQL 陳述式時,這是相當直接的,如以上的範例所示。 在這些情況下, 呼叫 SQLExecDirect 或 SQLExecute 會傳回SQL_ERROR或SQL_SUCCESS_WITH_INFO,然後可以呼叫 SQLGetDiagRec 。 撰寫程式碼迴圈來處理 SQL 語句批次的輸出,或在執行預存程式SQL Server時,比較不簡單。
在此情況下,SQL Server會針對批次或預存程式中執行的每個 SELECT 語句傳回結果集。 如果批次或程序包含 PRINT 或 RAISERROR 陳述式,這些陳述式的輸出會與 SELECT 陳述式結果集交錯。 如果批次或程式中的第一個語句是 PRINT 或 RAISERROR, SQLExecute 或 SQLExecDirect 會傳回SQL_SUCCESS_WITH_INFO或SQL_ERROR,而且應用程式必須呼叫 SQLGetDiagRec ,直到傳回SQL_NO_DATA以擷取 PRINT 或 RAISERROR 資訊為止。
如果 PRINT 或 RAISERROR 語句在 SQL 語句之後 (例如 SELECT 語句) ,則當 SQLMoreResults位於包含錯誤的結果集上時,會傳回 PRINT 或 RAISERROR 資訊。 SQLMoreResults 會 根據訊息的嚴重性傳回SQL_SUCCESS_WITH_INFO或SQL_ERROR。 呼叫 SQLGetDiagRec 以擷取訊息,直到傳回SQL_NO_DATA為止。