Elaborazione di istruzioni che generano messaggi
Le opzioni STATISTICS TIME e STATISTICS IO dell'istruzione SET Transact-SQL vengono utilizzate per ottenere informazioni utili per la diagnosi di query con esecuzione prolungata. Le versioni precedenti di SQL Server supportano inoltre l'opzione SHOWPLAN per l'analisi di piani di query. È possibile impostare queste opzioni in un'applicazione ODBC eseguendo le istruzioni seguenti:
SQLExecDirect(hstmt, "SET SHOWPLAN ON", SQL_NTS);
SQLExecDirect(hstmt, "SET STATISTICS TIME ON", SQL_NTS90
);
SQLExecDirect(hstmt, "SET STATISTICS IO ON", SQL_NTS);
Quando SET STATISTICS TIME o SET SHOWPLAN è ON, SQLExecute e SQLExecDirect restituiscono SQL_SUCCESS_WITH_INFO e, a quel punto, è possibile può recuperare l'output di SHOWPLAN o STATISTICS TIME chiamando SQLGetDiagRec fino a che non viene restituito SQL_NO_DATA. Ogni riga di dati SHOWPLAN viene restituita nel formato:
szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
Table Scan"
SQL Server versione 7.0 ha sostituito l'opzione SHOWPLAN con SHOWPLAN_ALL e SHOWPLAN_TEXT. Entrambe restituiscono l'output come set di risultati, non come set di messaggi.
Ogni riga di dati STATISTICS TIME viene restituita nel formato:
szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
SQL Server Parse and Compile Time: cpu time = 0 ms."
L'output di SET STATISTICS IO non è disponibile fino alla fine di un set di risultati. Per ottenere l'output di STATISTICS IO, viene chiamato SQLGetDiagRec quando SQLFetch o SQLFetchScroll restituisce SQL_NO_DATA. L'output di STATISTICS IO viene restituito nel formato:
szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table: testshow scan count 1, logical reads: 1,
physical reads: 0."
Utilizzo di istruzioni DBCC
Le istruzioni DBCC restituiscono i dati come messaggi, non come set di risultati. SQLExecDirect o SQLExecute restituiscono SQL_SUCCESS_WITH_INFO e l'output viene recuperato chiamando SQLGetDiagRec fino a che non viene restituito SQL_NO_DATA.
Nell'istruzione seguente, ad esempio, viene restituito SQL_SUCCESS_WITH_INFO:
SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);
Le chiamate a SQLGetDiagRec restituiscono:
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."
Utilizzo delle istruzioni PRINT e RAISERROR
Anche le istruzioni PRINT e RAISERROR di Transact-SQL restituiscono dati mediante la chiamata a SQLGetDiagRec. Le istruzioni PRINT comportano SQL_SUCCESS_WITH_INFO come risultato dell'esecuzione dell'istruzione SQL e una chiamata successiva a SQLGetDiagRec restituisce il valore 01000 per SQLState. Un'istruzione RAISERROR con livello di gravità dieci o inferiore si comporta esattamente come PRINT. Un'istruzione RAISERROR con livello di gravità 11 o superiore comporta SQL_ERROR come risultato dell'esecuzione e una successiva chiamata a SQLGetDiagRec restituisce il valore 42000 per SQLState. Nell'istruzione seguente, ad esempio, viene restituito SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS);
La chiamata a SQLGetDiagRec restituisce:
szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Some message"
Nell'istruzione seguente, ad esempio, viene restituito SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
SQL_NTS)
La chiamata a SQLGetDiagRec restituisce:
szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 1."
L'istruzione seguente restituisce SQL_ERROR:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)
La chiamata a SQLGetDiagRec restituisce:
szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 2."
L'intervallo della chiamata a SQLGetDiagRec è molto importante quando in un set di risultati è incluso l'output restituito dalle istruzioni PRINT o RAISERROR. La chiamata a SQLGetDiagRec per recuperare l'output di PRINT o RAISERROR deve essere effettuata immediatamente dopo l'istruzione che riceve SQL_ERROR o SQL_SUCCESS_WITH_INFO. Si tratta di un processo diretto quando viene eseguita una sola istruzione SQL, come negli esempi precedenti. In questi casi, la chiamata a SQLExecDirect o a SQLExecute restituisce SQL_ERROR o SQL_SUCCESS_WITH_INFO e potrà quindi essere chiamato SQLGetDiagRec. Il processo è meno diretto quando vengono codificati i cicli per gestire l'output di un batch di istruzioni SQL o quando vengono eseguite le stored procedure di SQL Server.
In questo caso, SQL Server restituisce un set di risultati per ogni istruzione SELECT eseguita in un batch o in una stored procedure. Se il batch o la stored procedure contiene le istruzioni PRINT o RAISERROR, il relativo output viene interfacciato con il set di risultati dell'istruzione SELECT. Se la prima istruzione del batch o della stored procedure è PRINT o RAISERROR, SQLExecute o SQLExecDirect restituisce SQL_SUCCESS_WITH_INFO o SQL_ERROR ed è necessario chiamare SQLGetDiagRec fino a che non viene restituito SQL_NO_DATA per recuperare le informazioni di PRINT o RAISERROR.
Se l'istruzione PRINT o RAISERROR viene dopo un'istruzione SQL (ad esempio un'istruzione SELECT), le informazioni di PRINT o RAISERROR vengono restituite quando SQLMoreResults viene inserito nel set di risultati che contiene l'errore. SQLMoreResults restituisce SQL_SUCCESS_WITH_INFO o SQL_ERROR, a seconda della gravità del messaggio. I messaggi vengono recuperati chiamando SQLGetDiagRec fino a che non viene restituito SQL_NO_DATA.