Обработка инструкций, выдающих сообщения
Параметры инструкции 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), то при позиции SQLMoreResults в результирующемнаборе, содержающем ошибку, возвращаются сведения PRINT или RAISERROR. SQLMoreResults возвращает SQL_SUCCESS_WITH_INFO или SQL_ERROR в зависимости от серьезности сообщения. Сообщения извлекаются путем вызова SQLGetDiagRec до тех пор, пока не будет возвращен SQL_NO_DATA.