Verarbeiten von Anweisungen, die Meldungen generieren
Die Transact-SQL-SET-Anweisungsoptionen STATISTICS TIME und STATISTICS IO werden verwendet, um Informationen zur Unterstützung bei der Diagnose von Abfragen mit langer Ausführungszeit zu gewinnen. Frühere Versionen von SQL Server unterstützen auch die SHOWPLAN-Option zur Analyse von Abfrageplänen. Eine ODBC-Anwendung kann diese Optionen festlegen, indem sie die folgenden Anweisungen ausführt:
SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS);
SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90
);
SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS);
Wenn für SET STATISTICS TIME oder SET SHOWPLAN ON festgelegt ist, geben SQLExecute und SQLExecDirect SQL_SUCCESS_WITH_INFO zurück, und zu diesem Punkt kann die Anwendung die Ausgabe von SHOWPLAN oder STATISTICS TIME durch Aufruf von SQLGetDiagRec abrufen, bis SQL_NO_DATA zurückgegeben wird. Jede Zeile der SHOWPLAN-Daten wird im folgenden Format ausgegeben:
szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
Table Scan"
In SQL Server Version 7.0 wurde die SHOWPLAN-Option durch SHOWPLAN_ALL und SHOWPLAN_TEXT ersetzt. Beide Optionen geben die Ausgabe als Resultset, nicht wie zuvor als Meldungssätze, zurück.
Jede Zeile der STATISTICS TIME-Daten wird im folgenden Format ausgegeben:
szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
SQL Server Parse and Compile Time: cpu time = 0 ms."
Die Ausgabe von SET STATISTICS IO ist bis zum Ende eines Resultsets nicht verfügbar. Um die Ausgabe von STATISTICS IO abzurufen, ruft die Anwendung SQLGetDiagRec auf, sobald SQLFetch oder SQLFetchScroll SQL_NO_DATA zurückgibt. Die Ausgabe der STATISTICS IO-Option erfolgt in folgendem Format:
szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table: testshow scan count 1, logical reads: 1,
physical reads: 0."
Verwenden von DBCC-Anweisungen
DBCC-Anweisungen geben Daten als Meldungen, nicht als Resultsets, zurück. SQLExecDirect und SQLExecute geben SQL_SUCCESS_WITH_INFO zurück, und die Anwendung ruft die Ausgabe durch Aufruf von SQLGetDiagRec ab, bis SQL_NO_DATA zurückgegeben wird.
Beispielsweise gibt die folgende Anweisung SQL_SUCCESS_WITH_INFO zurück:
SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);
Aufrufe von SQLGetDiagRec geben Folgendes zurück:
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."
Verwenden der Anweisungen PRINT und RAISERROR
Auch Transact-SQL-PRINT- und RAISERROR-Anweisungen geben Daten zurück, indem sie SQLGetDiagRec aufrufen. Mit PRINT-Anweisungen wird durch die SQL-Anweisungsausführung SQL_SUCCESS_WITH_INFO zurückgegeben, und ein anschließender Aufruf von SQLGetDiagRec gibt SQLState 01000 zurück. Ein RAISERROR mit einem Schweregrad bis einschließlich 10 zeigt dasselbe Verhalten wie PRINT. Bei einem RAISERROR mit einem Schweregrad ab 11 wird bei der Ausführung SQL_ERROR zurückgegeben, und ein anschließender Aufruf von SQLGetDiagRec gibt SQLState 42000 zurück. Beispielsweise gibt die folgende Anweisung SQL_SUCCESS_WITH_INFO zurück:
SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS);
Ein Aufruf von SQLGetDiagRec gibt Folgendes zurück:
szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Some message"
Die folgende Anweisung gibt SQL_SUCCESS_WITH_INFO zurück:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
SQL_NTS)
Ein Aufruf von SQLGetDiagRec gibt Folgendes zurück:
szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 1."
Die folgende Anweisung gibt SQL_ERROR zurück:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)
Ein Aufruf von SQLGetDiagRec gibt Folgendes zurück:
szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 2."
Der Zeitpunkt, zu dem SQLGetDiagRec aufgerufen wird, ist kritisch, wenn Ausgaben von PRINT- oder RAISERROR-Anweisungen in ein Resultset aufgenommen werden sollen. Der Aufruf von SQLGetDiagRec zum Abrufen der Ausgabe von PRINT oder RAISERROR muss unmittelbar nach der Anweisung erfolgen, die SQL_ERROR oder SQL_SUCCESS_WITH_INFO empfängt. Dies ist einfach, wenn nur eine einzelne SQL-Anweisung ausgeführt wird, wie in den oben stehenden Beispielen. In diesen Fällen gibt der Aufruf von SQLExecDirect oder SQLExecute SQL_ERROR oder SQL_SUCCESS_WITH_INFO zurück, und anschließend kann SQLGetDiagRec aufgerufen werden. Komplizierter wird es, wenn Schleifen zum Behandeln der Ausgabe einer Reihe von SQL-Anweisungen codiert, oder wenn SQL Server-gespeicherte Prozeduren ausgeführt werden müssen.
In diesem Fall gibt SQL Server ein Resultset für jede SELECT-Anweisung zurück, die in einem Batch oder in einer gespeicherten Prozedur ausgeführt wurde. Wenn der Batch bzw. die Prozedur PRINT- oder RAISERROR-Anweisungen enthält, ist die Ausgabe dieser Anweisungen mit den Resultsets der SELECT-Anweisungen verschachtelt. Wenn die erste Anweisung im Batch bzw. in der Prozedur PRINT oder RAISERROR ist, gibt SQLExecute oder SQLExecDirect SQL_SUCCESS_WITH_INFO oder SQL_ERROR zurück, und die Anwendung muss SQLGetDiagRec aufrufen, bis SQL_NO_DATA zurückgegeben wird, um die PRINT- oder RAISERROR-Informationen zu erhalten.
Steht die PRINT- oder RAISERROR-Anweisung nach einer SQL-Anweisung (wie beispielsweise einer SELECT-Anweisung), werden die PRINT- oder RAISERROR-Informationen zurückgegeben, wenn SQLMoreResults auf dem Resultset positioniert wird, das den Fehler enthält. SQLMoreResults gibt abhängig vom Schweregrad des Fehlers SQL_SUCCESS_WITH_INFO oder SQL_ERROR zurück. Die Meldungen werden abgerufen, indem SQLGetDiagRec aufgerufen wird, bis SQL_NO_DATA zurückgegeben wird.