Processando instruções que geram mensagens
As opções STATISTICS TIME e STATISTICS IO da instrução SET do Transact-SQL são usadas para obter informações que auxiliem a diagnosticar consultas de longa execução. As versões anteriores do SQL Server também dão suporte à opção SHOWPLAN para analisar planos de consulta. Um aplicativo ODBC pode definir essas opções executando as seguintes instruções:
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 ou SET SHOWPLAN forem ON, SQLExecute e SQLExecDirect retornarão SQL_SUCCESS_WITH_INFO e, nesse momento, o aplicativo poderá recuperar a saída de SHOWPLAN ou STATISTICS TIME chamando SQLGetDiagRec até ele retornar SQL_NO_DATA. Cada linha de dados de SHOWPLAN volta no formato:
szSqlState="01000", *pfNativeError=6223,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
Table Scan"
O SQL Server versão 7.0 substituiu a opção SHOWPLAN por SHOWPLAN_ALL e SHOWPLAN_TEXT, que retornam a saída como um conjunto de resultados e não um conjunto de mensagens.
Cada linha de STATISTICS TIME volta no formato:
szSqlState="01000", *pfNativeError= 3613,
szErrorMsg="[Microsoft][SQL Server Native Client][SQL Server]
SQL Server Parse and Compile Time: cpu time = 0 ms."
A saída de SET STATISTICS IO não está disponível até o final de um conjunto de resultados. Para obter a saída de STATISTICS IO, o aplicativo chama SQLGetDiagRec no momento em que SQLFetch ou SQLFetchScroll retorna SQL_NO_DATA. A saída de STATISTICS IO volta no formato:
szSqlState="01000", *pfNativeError= 3615,
szErrorMsg="[Microsoft][ SQL Server Native Client][SQL Server]
Table: testshow scan count 1, logical reads: 1,
physical reads: 0."
Usando instruções DBCC
As instruções DBCC retornam seus dados como mensagens, não como conjuntos de resultados. SQLExecDirect ou SQLExecute retornam SQL_SUCCESS_WITH_INFO e o aplicativo recupera a saída chamando SQLGetDiagRec até ele retornar SQL_NO_DATA.
Por exemplo, a instrução a seguir retorna SQL_SUCCESS_WITH_INFO:
SQLExecDirect(hstmt, "DBCC CHECKTABLE(Authors)", SQL_NTS);
As chamadas de SQLGetDiagRec retornam:
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."
Usando as instruções PRINT e RAISERROR
As instruções PRINT e RAISERROR do Transact-SQL também retornam dados chamando SQLGetDiagRec. As instruções PRINT fazem a execução da instrução SQL retornar SQL_SUCCESS_WITH_INFO e uma chamada subseqüente de SQLGetDiagRec retornar um SQLSTATE igual a 01000. Um RAISERROR com uma severidade de dez ou menor se comporta da mesma forma que PRINT. Um RAISERROR com uma severidade de 11 ou maior faz a execução retornar SQL_ERROR e uma chamada subseqüente de SQLGetDiagRec retornar um SQLSTATE 42000. Por exemplo, a instrução a seguir retorna SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "PRINT 'Some message' ", SQL_NTS);
A chamada de SQLGetDiagRec retorna:
szSQLState = "01000", *pfNative Error = 0,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Some message"
A instrução a seguir retorna SQL_SUCCESS_WITH_INFO:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 1.', 10, -1)",
SQL_NTS)
A chamada de SQLGetDiagRec retorna:
szSQLState = "01000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 1."
A instrução a seguir retorna SQL_ERROR:
SQLExecDirect (hstmt, "RAISERROR ('Sample error 2.', 11, -1)", SQL_NTS)
A chamada de SQLGetDiagRec retorna:
szSQLState = "42000", *pfNative Error = 50000,
szErrorMsg= "[Microsoft] [SQL Server Native Client][SQL Server]
Sample error 2."
O controle de tempo da chamada de SQLGetDiagRec é crítica quando a saída de instruções PRINT ou RAISERROR são incluídas em um conjunto de resultados. A chamada de SQLGetDiagRec para recuperar a saída de PRINT ou RAISERROR deve ser feita imediatamente depois da instrução que recebe SQL_ERROR ou SQL_SUCCESS_WITH_INFO. Isto é direto quando apenas uma única instrução SQL é executada, como nos exemplos acima. Nesses casos, a chamada de SQLExecDirect ou SQLExecute retorna SQL_ERROR ou SQL_SUCCESS_WITH_INFO e SQLGetDiagRec pode ser chamado em seguida. Isso é menos direto quando ao codificar loops para tratar a saída de um lote de instruções SQL ou ao executar procedimentos armazenados do SQL Server.
Neste caso, o SQL Server retorna um conjunto de resultados para cada instrução SELECT executada em um lote ou um procedimento armazenado. Se o lote ou o procedimento contiver instruções PRINT ou RAISERROR, sua saída será intercalada com os conjuntos de resultados da instrução SELECT. Se a primeira instrução no lote ou no procedimento for PRINT ou RAISERROR, o SQLExecute ou SQLExecDirect retornará SQL_SUCCESS_WITH_INFO ou SQL_ERROR, e o aplicativo precisará chamar SQLGetDiagRec até ele retornar SQL_NO_DATA para recuperar as informações de PRINT ou RAISERROR.
Se a instrução PRINT ou RAISERROR vier depois de uma instrução SQL (como uma instrução SELECT), as informações de PRINT ou de RAISERROR serão retornadas quando SQLMoreResultsse posicionar no conjunto de resultados que contém o erro. SQLMoreResults retorna SQL_SUCCESS_WITH_INFO ou SQL_ERROR, dependendo da severidade da mensagem. Mensagens são recuperadas chamando SQLGetDiagRec até ele retornar SQL_NO_DATA.