Recuperando informações de erro em Transact-SQL

Há dois modos para obter informações de erro no Transact-SQL:

  • Dentro do escopo do bloco CATCH de uma construção TRY.CATCH, você pode usar as seguintes funções de sistema:

    • ERROR_LINE() retorna o número de linha na qual ocorreu o erro.

    • ERROR_MESSAGE () retorna o texto da mensagem que retornaria ao aplicativo. O texto inclui os valores fornecidos para qualquer parâmetro substituível, como comprimentos, nomes de objeto ou horas.

    • ERROR_NUMBER () retorna o número do erro.

    • ERROR_PROCEDURE() retorna o nome do procedimento armazenado ou gatilho no qual ocorreu o erro. Esta função retorna o NULL se o erro não ocorreu dentro de um procedimento armazenado ou gatilho.

    • ERROR_SEVERITY() retorna a severidade..

    • ERROR_STATE () retorna o estado.

  • Imediatamente após executar qualquer instrução Transact-SQL, você pode fazer teste para erros e recuperar o número do erro usando a função @@ERROR.

Usando ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY e ERROR_STATE

As funções ERROR_LINE, ERROR_MESSAGE, ERROR_PROCEDURE, ERROR_NUMBER, ERROR_SEVERITY e ERROR_STATE somente retornam informações sobre erros quando forem usadas dentro do escopo do bloco CATCH de uma construção TRY...CATCH. Fora do escopo de um bloco CAPTURA, elas retornam NULL. Essas funções retornam informações sobre o erro que fez o bloco CATCH ser invocado. As funções retornam as mesmas informações de erro em qualquer local onde forem executadas, no escopo de um bloco CATCH, mesmo que referenciadas diversas vezes. As funções fornecem às instruções Transact-SQL os mesmos dados que retornam ao aplicativo.

Em blocos CATCH aninhados as funções ERROR_LINE, ERROR_MESSAGE, ERROR_PROCEDURE, ERROR_NUMBER, ERROR_SEVERITY e ERROR_STATE retornam as informações sobre erros específicas do bloco CATCH, no qual são referenciadas. Por exemplo, o bloco CATCH de uma construção TRY...CATCH externa poderia ter uma construção TRY...CATCH aninhada. Dentro do bloco CATCH aninhado, essas funções retornam informações sobre o erro que invocou o bloco CATCH interno. As mesmas funções no bloco CATCH exterior retornariam informações sobre o erro que invocou aquele bloco CATCH .

O exemplo a seguir ilustra isso, ao mostrar que, quando ERROR_MESSAGE é referenciado no bloco CATCH, ela retorna o texto da mensagem gerado por outro bloco TRY. Quando for referenciado no bloco CATCH interno, a ERROR_MESSAGE retorna o texto gerado no bloco interno TRY. O exemplo ilustra também que, no bloco CATCH, ERROR_MESSAGE sempre retorna a mensagem gerada no bloco TRY externo, mesmo depois de a construção interna TRY...CATCH ter sido executada.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Message text is from the %s TRY block.';
GO
BEGIN TRY -- Outer TRY block.
    -- Raise an error in the outer TRY block.
    RAISERROR (50010, -- Message id.
        16, -- Severity,
        1, -- State,
        N'outer'); -- Indicate TRY block.
END TRY -- Outer TRY block.
BEGIN CATCH -- Outer CATCH block.
    -- Print the error message recieved for this
    -- CATCH block.
    PRINT N'OUTER CATCH1: ' + ERROR_MESSAGE();
    BEGIN TRY -- Inner TRY block.
        -- Start a nested TRY...CATCH and generate
        -- a new error.
        RAISERROR (50010, -- Message id.
            16, -- Severity,
            2, -- State,
            N'inner'); -- Indicate TRY block.
    END TRY -- Inner TRY block.
    BEGIN CATCH -- Inner CATCH block.
        -- Print the error message recieved for this
        -- CATCH block.
        PRINT N'INNER CATCH: ' + ERROR_MESSAGE();
    END CATCH; -- Inner CATCH block.
    -- Show that ERROR_MESSAGE in the outer CATCH
    -- block still returns the message from the
    -- error generated in the outer TRY block.
    PRINT N'OUTER CATCH2: ' + ERROR_MESSAGE();
END CATCH; -- Outer CATCH block.
GO

Recuperando informações usando @@ERROR

A função @@ERROR pode ser usada para capturar o número de um erro gerado pela instrução Transact-SQL anterior. @@ERROR somente retorna informações de erro imediatamente após a instrução Transact-SQL que gera o erro.

  • Se a instrução que gera o erro não estiver no bloco TRY, o valor @@ERROR deve ser testado e recuperado na primeira instrução do bloco CATCH associado.

  • Se a instrução que gera o erro não estiver no bloco TRY, o valor @@ERROR deve ser testado e recuperado na instrução, imediatamente após a que gerou o erro.

Fora do escopo de um bloco CATCH, o número do erro em @@ERROR é a única informação disponível sobre um erro no códigoTransact-SQL. Se o erro usou uma mensagem de erro definida em sys.messages, você pode recuperar a severidade definida e o texto da mensagem de erro de sys.messages, conforme ilustrado neste exemplo.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
-- Define a message with text that accepts
-- a substitution string.
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Substitution string = %s.';
GO
DECLARE @ErrorVariable INT;
-- RAISERROR uses a different severity and
-- supplies a substitution argument.
RAISERROR (50010, -- Message id.
    15, -- Severity,
    1, -- State,
    N'ABC'); -- Substitution Value.
-- Save @@ERROR.
SET @ErrorVariable = @@ERROR;
-- The results of this select illustrate that
-- outside a CATCH block only the original
-- information from sys.messages is available to
-- Transact-SQL statements. The actual message
-- string returned to the application is not
-- available to Transact-SQL statements outside
-- of a CATCH block.
SELECT @ErrorVariable AS ErrorID,
    text
FROM sys.messages
WHERE message_id = @ErrorVariable;
GO