TRY...CATCH (Transact-SQL)TRY...CATCH (Transact-SQL)

APLICA-SE A: simSQL Server simBanco de Dados SQL do Azure simSQL Data Warehouse do Azure simParallel Data Warehouse APPLIES TO: yesSQL Server yesAzure SQL Database yesAzure SQL Data Warehouse yesParallel Data Warehouse

Implementa tratamento de erros para Transact-SQLTransact-SQL semelhante ao tratamento de exceções nas linguagens MicrosoftMicrosoft Visual C# e MicrosoftMicrosoft Visual C++.Implements error handling for Transact-SQLTransact-SQL that is similar to the exception handling in the MicrosoftMicrosoft Visual C# and MicrosoftMicrosoft Visual C++ languages. Um grupo de instruções Transact-SQLTransact-SQL pode ser incluído em um bloco TRY.A group of Transact-SQLTransact-SQL statements can be enclosed in a TRY block. Se ocorrer um erro no bloco TRY, o controle passará para outro grupo de instruções que está incluído em um bloco CATCH.If an error occurs in the TRY block, control is passed to another group of statements that is enclosed in a CATCH block.

Ícone de link do tópico Convenções de sintaxe de Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintaxeSyntax

BEGIN TRY  
     { sql_statement | statement_block }  
END TRY  
BEGIN CATCH  
     [ { sql_statement | statement_block } ]  
END CATCH  
[ ; ]  

ArgumentosArguments

sql_statementsql_statement
É qualquer instrução Transact-SQLTransact-SQL.Is any Transact-SQLTransact-SQL statement.

statement_blockstatement_block
Qualquer grupo de instruções Transact-SQLTransact-SQL em um lote ou incluso em um bloco BEGIN...END.Any group of Transact-SQLTransact-SQL statements in a batch or enclosed in a BEGIN...END block.

RemarksRemarks

Um constructo TRY...CATCH captura todos os erros de execução com gravidade maior que 10 que não fecham a conexão de banco de dados.A TRY...CATCH construct catches all execution errors that have a severity higher than 10 that do not close the database connection.

Um bloco TRY deve ser seguido imediatamente por um bloco CATCH associado.A TRY block must be immediately followed by an associated CATCH block. A inclusão de qualquer outra instrução entre as instruções END TRY e BEGIN CATCH gera um erro de sintaxe.Including any other statements between the END TRY and BEGIN CATCH statements generates a syntax error.

Um constructo TRY...CATCH não pode abranger vários lotes.A TRY...CATCH construct cannot span multiple batches. Um constructo TRY...CATCH não pode abranger vários blocos de instruções Transact-SQLTransact-SQL.A TRY...CATCH construct cannot span multiple blocks of Transact-SQLTransact-SQL statements. Por exemplo, um constructo TRY...CATCH não pode abranger dois blocos BEGIN...END de instruções Transact-SQLTransact-SQL e não pode abranger um constructo IF...ELSE.For example, a TRY...CATCH construct cannot span two BEGIN...END blocks of Transact-SQLTransact-SQL statements and cannot span an IF...ELSE construct.

Se não houver erros no código incluído em um bloco TRY, quando a execução da última instrução no bloco TRY for concluída, o controle passará para a instrução imediatamente posterior à instrução END CATCH associada.If there are no errors in the code that is enclosed in a TRY block, when the last statement in the TRY block has finished running, control passes to the statement immediately after the associated END CATCH statement. Se houver um erro no código incluído em um bloco TRY, o controle passará para a primeira instrução do bloco CATCH associado.If there is an error in the code that is enclosed in a TRY block, control passes to the first statement in the associated CATCH block. Se a instrução END CATCH for a última instrução de um procedimento armazenado ou gatilho, o controle voltará para a instrução que chamou o procedimento armazenado ou acionou o gatilho.If the END CATCH statement is the last statement in a stored procedure or trigger, control is passed back to the statement that called the stored procedure or fired the trigger.

Quando o código no bloco CATCH for concluído, o controle passará para a instrução imediatamente posterior à instrução END CATCH.When the code in the CATCH block finishes, control passes to the statement immediately after the END CATCH statement. Os erros interceptados por um bloco CATCH não são retornados ao aplicativo que o chamou.Errors trapped by a CATCH block are not returned to the calling application. Se qualquer parte das informações de erro precisar ser retornada ao aplicativo, o código no bloco CATCH deverá fazê-lo usando mecanismos como conjuntos de resultados SELECT ou as instruções RAISERROR e PRINT.If any part of the error information must be returned to the application, the code in the CATCH block must do so by using mechanisms such as SELECT result sets or the RAISERROR and PRINT statements.

Os constructos TRY...CATCH podem ser aninhados.TRY...CATCH constructs can be nested. Um bloco TRY ou um bloco CATCH pode conter constructos TRY...CATCH aninhados.Either a TRY block or a CATCH block can contain nested TRY...CATCH constructs. Por exemplo, um bloco CATCH pode conter um constructo TRY...CATCH inserido para tratar erros encontrados pelo código CATCH.For example, a CATCH block can contain an embedded TRY...CATCH construct to handle errors encountered by the CATCH code.

Os erros encontrados em um bloco CATCH são tratados como erros gerados em qualquer outro lugar.Errors encountered in a CATCH block are treated like errors generated anywhere else. Se o bloco CATCH contiver um constructo TRY...CATCH aninhado, qualquer erro no bloco TRY aninhado passará o controle para o bloco CATCH aninhado.If the CATCH block contains a nested TRY...CATCH construct, any error in the nested TRY block will pass control to the nested CATCH block. Se não houver nenhum constructo TRY...CATCH aninhado, o erro voltará para o chamador.If there is no nested TRY...CATCH construct, the error is passed back to the caller.

Os constructos TRY...CATCH capturam erros não tratados de procedimentos armazenados nem gatilhos executados pelo código do bloco TRY.TRY...CATCH constructs catch unhandled errors from stored procedures or triggers executed by the code in the TRY block. Como alternativa, os procedimentos armazenados ou os gatilhos podem conter os próprios constructos TRY...CATCH para tratar os erros gerados por seu código.Alternatively, the stored procedures or triggers can contain their own TRY...CATCH constructs to handle errors generated by their code. Por exemplo, quando um bloco TRY executa um procedimento armazenado e ocorre um erro no procedimento, o erro pode ser tratado das seguintes maneiras:For example, when a TRY block executes a stored procedure and an error occurs in the stored procedure, the error can be handled in the following ways:

  • Se o procedimento armazenado não contiver seu próprio constructo TRY...CATCH, o erro retornará o controle para o bloco CATCH associado ao bloco TRY que contém a instrução EXECUTE.If the stored procedure does not contain its own TRY...CATCH construct, the error returns control to the CATCH block associated with the TRY block that contains the EXECUTE statement.

  • Se o procedimento armazenado contiver um constructo TRY...CATCH, o erro transferirá o controle para o bloco CATCH do procedimento armazenado.If the stored procedure contains a TRY...CATCH construct, the error transfers control to the CATCH block in the stored procedure. Quando o código do bloco CATCH for concluído, o controle voltará para a instrução imediatamente posterior à instrução EXECUTE que chamou o procedimento armazenado.When the CATCH block code finishes, control is passed back to the statement immediately after the EXECUTE statement that called the stored procedure.

As instruções GOTO não podem ser usadas para inserir um bloco TRY ou CATCH.GOTO statements cannot be used to enter a TRY or CATCH block. As instruções GOTO podem ser usadas para saltar para um rótulo dentro do mesmo bloco TRY ou CATCH ou para sair de um bloco TRY ou CATCH.GOTO statements can be used to jump to a label inside the same TRY or CATCH block or to leave a TRY or CATCH block.

O constructo TRY...CATCH não pode ser usado em uma função definida pelo usuário.The TRY...CATCH construct cannot be used in a user-defined function.

Recuperando informações de erroRetrieving Error Information

No escopo de um bloco CATCH, as seguintes funções de sistema podem ser usadas para obter informações sobre o erro que causou a execução do bloco CATCH.In the scope of a CATCH block, the following system functions can be used to obtain information about the error that caused the CATCH block to be executed:

  • ERROR_NUMBER() retorna o número do erro.ERROR_NUMBER() returns the number of the error.

  • ERROR_SEVERITY() retorna a severidade.ERROR_SEVERITY() returns the severity.

  • ERROR_STATE() retorna o número do estado do erro.ERROR_STATE() returns the error state number.

  • ERROR_PROCEDURE() retorna o nome do procedimento armazenado ou do gatilho no qual ocorreu o erro.ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred.

  • ERROR_LINE() retorna o número de linha dentro da rotina que causou o erro.ERROR_LINE() returns the line number inside the routine that caused the error.

  • ERROR_MESSAGE() retorna o texto completo da mensagem de erro.ERROR_MESSAGE() returns the complete text of the error message. O texto inclui os valores fornecidos para qualquer parâmetro substituível, como comprimentos, nomes de objeto ou horas.The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

Essas funções retornarão NULL se forem chamadas fora do escopo do bloco CATCH.These functions return NULL if they are called outside the scope of the CATCH block. As informações de erro podem ser recuperadas com o uso dessas funções em qualquer lugar no escopo do bloco CATCH.Error information can be retrieved by using these functions from anywhere within the scope of the CATCH block. Por exemplo, o script a seguir mostra um procedimento armazenado que contém funções de tratamento de erros.For example, the following script shows a stored procedure that contains error-handling functions. No bloco CATCH de uma construção TRY...CATCH, o procedimento armazenado é chamado e as informações sobre o erro são retornadas.In the CATCH block of a TRY...CATCH construct, the stored procedure is called and information about the error is returned.

-- Verify that the stored procedure does not already exist.  
IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL   
    DROP PROCEDURE usp_GetErrorInfo;  
GO  
  
-- Create procedure to retrieve error information.  
CREATE PROCEDURE usp_GetErrorInfo  
AS  
SELECT  
    ERROR_NUMBER() AS ErrorNumber  
    ,ERROR_SEVERITY() AS ErrorSeverity  
    ,ERROR_STATE() AS ErrorState  
    ,ERROR_PROCEDURE() AS ErrorProcedure  
    ,ERROR_LINE() AS ErrorLine  
    ,ERROR_MESSAGE() AS ErrorMessage;  
GO  
  
BEGIN TRY  
    -- Generate divide-by-zero error.  
    SELECT 1/0;  
END TRY  
BEGIN CATCH  
    -- Execute error retrieval routine.  
    EXECUTE usp_GetErrorInfo;  
END CATCH;   

As funções ERROR_* também funcionam em um bloco CATCH dentro de um procedimento armazenado compilado nativamente.The ERROR_* functions also work in a CATCH block inside a natively compiled stored procedure.

Erros não afetados por um constructo TRY...CATCHErrors Unaffected by a TRY...CATCH Construct

Os constructos TRY...CATCH não interceptam as seguintes condições:TRY...CATCH constructs do not trap the following conditions:

  • Avisos ou mensagens informativas que têm uma severidade 10 ou menor.Warnings or informational messages that have a severity of 10 or lower.

  • Erros que têm uma severidade 20 ou maior, que param o processamento de tarefa do Mecanismo de Banco de Dados do SQL ServerSQL Server Database Engine para a sessão.Errors that have a severity of 20 or higher that stop the Mecanismo de Banco de Dados do SQL ServerSQL Server Database Engine task processing for the session. Se ocorrer um erro com gravidade 20 ou maior e a conexão de banco de dados não for interrompida, TRY...CATCH tratará o erro.If an error occurs that has severity of 20 or higher and the database connection is not disrupted, TRY...CATCH will handle the error.

  • Atenções, como solicitações da interrupção de cliente ou conexões de cliente desfeitas.Attentions, such as client-interrupt requests or broken client connections.

  • Quando a sessão for finalizada por um administrador de sistema com o uso da instrução KILL.When the session is ended by a system administrator by using the KILL statement.

Os seguintes tipos de erros não são tratados por um bloco CATCH quando ocorrerem no mesmo nível de execução que o constructo TRY...CATCH:The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY...CATCH construct:

  • Erros de compilação, como erros de sintaxe, que impeçam a execução de um lote.Compile errors, such as syntax errors, that prevent a batch from running.

  • Erros que ocorrem durante a recompilação em nível de instrução, como os erros de resolução do nome de objeto que ocorrem após a compilação, devido à resolução adiada do nome.Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.

  • Erros de resolução de nome de objetoObject name resolution errors

Esses erros são retornados ao nível que executou o lote, o procedimento armazenado ou o gatilho.These errors are returned to the level that ran the batch, stored procedure, or trigger.

Se ocorrer um erro durante a compilação ou a recompilação no nível da instrução em um nível de execução inferior (por exemplo, ao executar sp_executesql ou um procedimento armazenado definido pelo usuário) dentro do bloco TRY, o erro ocorrerá em um nível inferior ao do constructo TRY...CATCH e será tratado pelo bloco CATCH associado.If an error occurs during compilation or statement-level recompilation at a lower execution level (for example, when executing sp_executesql or a user-defined stored procedure) inside the TRY block, the error occurs at a lower level than the TRY...CATCH construct and will be handled by the associated CATCH block.

O exemplo a seguir mostra como um erro de resolução de nome de objeto gerado por uma instrução SELECT não é capturado pela construção TRY...CATCH, mas é capturado pelo bloco CATCH quando a mesma instrução SELECT é executada dentro de um procedimento armazenado.The following example shows how an object name resolution error generated by a SELECT statement is not caught by the TRY...CATCH construct, but is caught by the CATCH block when the same SELECT statement is executed inside a stored procedure.

BEGIN TRY  
    -- Table does not exist; object name resolution  
    -- error not caught.  
    SELECT * FROM NonexistentTable;  
END TRY  
BEGIN CATCH  
    SELECT   
        ERROR_NUMBER() AS ErrorNumber  
       ,ERROR_MESSAGE() AS ErrorMessage;  
END CATCH  

O erro não é capturado e o controle é transmitido para fora da construção TRY...CATCH para o próximo nível mais alto.The error is not caught and control passes out of the TRY...CATCH construct to the next higher level.

A execução da instrução SELECT dentro de um procedimento armazenado fará com que o erro ocorra em um nível inferior ao do bloco TRY.Running the SELECT statement inside a stored procedure will cause the error to occur at a level lower than the TRY block. O erro será tratado pela construção TRY...CATCH.The error will be handled by the TRY...CATCH construct.

-- Verify that the stored procedure does not exist.  
IF OBJECT_ID ( N'usp_ExampleProc', N'P' ) IS NOT NULL   
    DROP PROCEDURE usp_ExampleProc;  
GO  
  
-- Create a stored procedure that will cause an   
-- object resolution error.  
CREATE PROCEDURE usp_ExampleProc  
AS  
    SELECT * FROM NonexistentTable;  
GO  
  
BEGIN TRY  
    EXECUTE usp_ExampleProc;  
END TRY  
BEGIN CATCH  
    SELECT   
        ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_MESSAGE() AS ErrorMessage;  
END CATCH;  

Transações não confirmáveis e XACT_STATEUncommittable Transactions and XACT_STATE

Se um erro gerado em um bloco TRY fizer com que o estado da transação atual seja invalidado, a transação será classificada como não confirmável.If an error generated in a TRY block causes the state of the current transaction to be invalidated, the transaction is classified as an uncommittable transaction. Um erro que normalmente finaliza uma transação fora de um bloco TRY faz com que uma transação entre em um estado não confirmável quando o erro ocorre dentro de um bloco TRY.An error that ordinarily ends a transaction outside a TRY block causes a transaction to enter an uncommittable state when the error occurs inside a TRY block. Uma transação não confirmável só pode executar operações de leitura ou uma ROLLBACK TRANSACTION.An uncommittable transaction can only perform read operations or a ROLLBACK TRANSACTION. A transação não pode executar nenhuma instrução Transact-SQLTransact-SQL que geraria uma operação de gravação ou uma COMMIT TRANSACTION.The transaction cannot execute any Transact-SQLTransact-SQL statements that would generate a write operation or a COMMIT TRANSACTION. A função XACT_STATE retornará o valor -1 se uma transação foi classificada como não confirmável.The XACT_STATE function returns a value of -1 if a transaction has been classified as an uncommittable transaction. Quando um lote é concluído, o Mecanismo de Banco de DadosDatabase Engine reverte quaisquer transações ativas não confirmáveis.When a batch finishes, the Mecanismo de Banco de DadosDatabase Engine rolls back any active uncommittable transactions. Se nenhuma mensagem de erro foi enviada quando a transação entrou em um estado não confirmável, quando o lote terminar, uma mensagem de erro será enviada ao aplicativo cliente.If no error message was sent when the transaction entered an uncommittable state, when the batch finishes, an error message will be sent to the client application. Isso indica que uma transação não confirmável foi detectada e revertida.This indicates that an uncommittable transaction was detected and rolled back.

Para obter mais informações sobre transações não confirmáveis e a função XACT_STATE, consulte XACT_STATE (Transact-SQL).For more information about uncommittable transactions and the XACT_STATE function, see XACT_STATE (Transact-SQL).

ExemplosExamples

A.A. Usando TRY...CATCHUsing TRY...CATCH

O exemplo a seguir mostra uma instrução SELECT que gerará um erro de divisão por zero.The following example shows a SELECT statement that will generate a divide-by-zero error. O erro faz com que a execução salte para o bloco CATCH associado.The error causes execution to jump to the associated CATCH block.

BEGIN TRY  
    -- Generate a divide-by-zero error.  
    SELECT 1/0;  
END TRY  
BEGIN CATCH  
    SELECT  
        ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_SEVERITY() AS ErrorSeverity  
        ,ERROR_STATE() AS ErrorState  
        ,ERROR_PROCEDURE() AS ErrorProcedure  
        ,ERROR_LINE() AS ErrorLine  
        ,ERROR_MESSAGE() AS ErrorMessage;  
END CATCH;  
GO  

B.B. Usando TRY...CATCH em uma transaçãoUsing TRY...CATCH in a transaction

O exemplo a seguir mostra como um bloco TRY...CATCH funciona dentro de uma transação.The following example shows how a TRY...CATCH block works inside a transaction. A instrução dentro do bloco TRY gera um erro de violação de restrição.The statement inside the TRY block generates a constraint violation error.

BEGIN TRANSACTION;  
  
BEGIN TRY  
    -- Generate a constraint violation error.  
    DELETE FROM Production.Product  
    WHERE ProductID = 980;  
END TRY  
BEGIN CATCH  
    SELECT   
        ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_SEVERITY() AS ErrorSeverity  
        ,ERROR_STATE() AS ErrorState  
        ,ERROR_PROCEDURE() AS ErrorProcedure  
        ,ERROR_LINE() AS ErrorLine  
        ,ERROR_MESSAGE() AS ErrorMessage;  
  
    IF @@TRANCOUNT > 0  
        ROLLBACK TRANSACTION;  
END CATCH;  
  
IF @@TRANCOUNT > 0  
    COMMIT TRANSACTION;  
GO  

C.C. Usando TRY...CATCH com XACT_STATEUsing TRY...CATCH with XACT_STATE

O exemplo a seguir mostra como usar a construção TRY...CATCH para tratar erros que ocorrem dentro de uma transação.The following example shows how to use the TRY...CATCH construct to handle errors that occur inside a transaction. A função XACT_STATE determina se a transação deve ser confirmada ou revertida.The XACT_STATE function determines whether the transaction should be committed or rolled back. Neste exemplo, SET XACT_ABORT é ON.In this example, SET XACT_ABORT is ON. Isso torna a transação não confirmável quando o erro de violação de restrição ocorrer.This makes the transaction uncommittable when the constraint violation error occurs.

-- Check to see whether this stored procedure exists.  
IF OBJECT_ID (N'usp_GetErrorInfo', N'P') IS NOT NULL  
    DROP PROCEDURE usp_GetErrorInfo;  
GO  
  
-- Create procedure to retrieve error information.  
CREATE PROCEDURE usp_GetErrorInfo  
AS  
    SELECT   
         ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_SEVERITY() AS ErrorSeverity  
        ,ERROR_STATE() AS ErrorState  
        ,ERROR_LINE () AS ErrorLine  
        ,ERROR_PROCEDURE() AS ErrorProcedure  
        ,ERROR_MESSAGE() AS ErrorMessage;  
GO  
  
-- SET XACT_ABORT ON will cause the transaction to be uncommittable  
-- when the constraint violation occurs.   
SET XACT_ABORT ON;  
  
BEGIN TRY  
    BEGIN TRANSACTION;  
        -- A FOREIGN KEY constraint exists on this table. This   
        -- statement will generate a constraint violation error.  
        DELETE FROM Production.Product  
            WHERE ProductID = 980;  
  
    -- If the DELETE statement succeeds, commit the transaction.  
    COMMIT TRANSACTION;  
END TRY  
BEGIN CATCH  
    -- Execute error retrieval routine.  
    EXECUTE usp_GetErrorInfo;  
  
    -- Test XACT_STATE:  
        -- If 1, the transaction is committable.  
        -- If -1, the transaction is uncommittable and should   
        --     be rolled back.  
        -- XACT_STATE = 0 means that there is no transaction and  
        --     a commit or rollback operation would generate an error.  
  
    -- Test whether the transaction is uncommittable.  
    IF (XACT_STATE()) = -1  
    BEGIN  
        PRINT  
            N'The transaction is in an uncommittable state.' +  
            'Rolling back transaction.'  
        ROLLBACK TRANSACTION;  
    END;  
  
    -- Test whether the transaction is committable.  
    IF (XACT_STATE()) = 1  
    BEGIN  
        PRINT  
            N'The transaction is committable.' +  
            'Committing transaction.'  
        COMMIT TRANSACTION;     
    END;  
END CATCH;  
GO  

Exemplos: Azure SQL Data WarehouseAzure SQL Data Warehouse e Parallel Data WarehouseParallel Data WarehouseExamples: Azure SQL Data WarehouseAzure SQL Data Warehouse and Parallel Data WarehouseParallel Data Warehouse

D.D. Usando TRY...CATCHUsing TRY...CATCH

O exemplo a seguir mostra uma instrução SELECT que gerará um erro de divisão por zero.The following example shows a SELECT statement that will generate a divide-by-zero error. O erro faz com que a execução salte para o bloco CATCH associado.The error causes execution to jump to the associated CATCH block.

BEGIN TRY  
    -- Generate a divide-by-zero error.  
    SELECT 1/0;  
END TRY  
BEGIN CATCH  
    SELECT  
        ERROR_NUMBER() AS ErrorNumber  
        ,ERROR_SEVERITY() AS ErrorSeverity  
        ,ERROR_STATE() AS ErrorState  
        ,ERROR_PROCEDURE() AS ErrorProcedure  
        ,ERROR_MESSAGE() AS ErrorMessage;  
END CATCH;  
GO  

Consulte TambémSee Also

THROW (Transact-SQL) THROW (Transact-SQL)
Gravidades de erros do mecanismo de banco de dados Database Engine Error Severities
ERROR_LINE (Transact-SQL) ERROR_LINE (Transact-SQL)
ERROR_MESSAGE (Transact-SQL) ERROR_MESSAGE (Transact-SQL)
ERROR_NUMBER (Transact-SQL) ERROR_NUMBER (Transact-SQL)
ERROR_PROCEDURE (Transact-SQL) ERROR_PROCEDURE (Transact-SQL)
ERROR_SEVERITY (Transact-SQL) ERROR_SEVERITY (Transact-SQL)
ERROR_STATE (Transact-SQL) ERROR_STATE (Transact-SQL)
RAISERROR (Transact-SQL) RAISERROR (Transact-SQL)
@@ERROR (Transact-SQL) @@ERROR (Transact-SQL)
GOTO (Transact-SQL) GOTO (Transact-SQL)
BEGIN...END (Transact-SQL) BEGIN...END (Transact-SQL)
XACT_STATE (Transact-SQL) XACT_STATE (Transact-SQL)
SET XACT_ABORT (Transact-SQL)SET XACT_ABORT (Transact-SQL)