Поделиться через


Обработка инструкций, выдающих сообщения

Применимо: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure azure Synapse Analytics Analytics Platform System (PDW)

Параметры инструкции 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, а в этом случае приложение может получить выходные данные SHOWPLAN или STATISTICS TIME, вызвав SQLGetDiagRec , пока не вернется 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, приложение вызывает SQLGetDiagRec в момент, когда SQLFetch или SQLFetchScroll возвращает SQL_NO_DATA. Выходные данные 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 возвращает SQLState 01000. Инструкция RAISERROR со степенью серьезности 10 или ниже работает так же, как PRINT. ФУНКЦИЯ RAISERROR с серьезностью 11 или выше приводит к возврату 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."  

Время вызова SQLGetDiagRec критически важно, если выходные данные инструкций PRINT или RAISERROR включены в результирующий набор. Вызов 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, то их выходные данные чередуются с результирующими наборами инструкций. Если первая инструкция в пакете или процедуре — PRINT или RAISERROR, SQLExecute или SQLExecDirect возвращает SQL_SUCCESS_WITH_INFO или SQL_ERROR, а приложение должно вызывать SQLGetDiagRec , пока не вернется SQL_NO_DATA для получения сведений PRINT или RAISERROR.

Если инструкция PRINT или RAISERROR возникает после инструкции SQL (например, инструкции SELECT), данные PRINT или RAISERROR возвращаются, когда sqlMoreResults позиций в результирующем наборе, содержающем ошибку. SQLMoreResults возвращает SQL_SUCCESS_WITH_INFO или SQL_ERROR в зависимости от серьезности сообщения. Сообщения извлекаются путем вызова SQLGetDiagRec , пока не возвращается SQL_NO_DATA.

См. также

Обработка ошибок и сообщений