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

SE APLICA A: síSQL Server síAzure SQL Database síAzure Synapse Analytics (SQL DW) síAlmacenamiento de datos paralelos APPLIES TO: yesSQL Server yesAzure SQL Database yesAzure Synapse Analytics (SQL DW) yesParallel Data Warehouse

Implementa un mecanismo de control de errores para Transact-SQLTransact-SQL que es similar al control de excepciones en los lenguajes MicrosoftMicrosoft Visual C# y 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. Se puede incluir un grupo de instrucciones Transact-SQLTransact-SQL en un bloque TRY.A group of Transact-SQLTransact-SQL statements can be enclosed in a TRY block. Si se produce un error en el bloque TRY, el control se transfiere a otro grupo de instrucciones que está incluido en un bloque CATCH.If an error occurs in the TRY block, control is passed to another group of statements that is enclosed in a CATCH block.

Icono de vínculo de tema Convenciones de sintaxis de Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintaxisSyntax

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

ArgumentosArguments

sql_statementsql_statement
Es cualquier instrucción Transact-SQLTransact-SQL.Is any Transact-SQLTransact-SQL statement.

statement_blockstatement_block
Grupo de instrucciones Transact-SQLTransact-SQL incluidas en un lote o en un bloque BEGIN…END.Any group of Transact-SQLTransact-SQL statements in a batch or enclosed in a BEGIN...END block.

NotasRemarks

Una construcción TRY…CATCH detecta todos los errores de ejecución que tienen una gravedad mayor de 10 y que no cierran la conexión de la base de datos.A TRY...CATCH construct catches all execution errors that have a severity higher than 10 that do not close the database connection.

Un bloque TRY debe ir seguido inmediatamente por un bloque CATCH asociado.A TRY block must be immediately followed by an associated CATCH block. Si se incluye cualquier otra instrucción entre las instrucciones END TRY y BEGIN CATCH se genera un error de sintaxis.Including any other statements between the END TRY and BEGIN CATCH statements generates a syntax error.

Una construcción TRY…CATCH no puede abarcar varios lotes.A TRY...CATCH construct cannot span multiple batches. Una construcción TRY…CATCH no puede abarcar varios bloques de instrucciones Transact-SQLTransact-SQL.A TRY...CATCH construct cannot span multiple blocks of Transact-SQLTransact-SQL statements. Por ejemplo, una construcción TRY…CATCH no puede abarcar dos bloques BEGIN…END de instrucciones Transact-SQLTransact-SQL, ni puede abarcar una construcción 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.

Si no hay errores en el código incluido en un bloque TRY, cuando la última instrucción de este bloque ha terminado de ejecutarse, el control se transfiere a la instrucción inmediatamente posterior a la instrucción END CATCH asociada.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. Si hay un error en el código incluido en un bloque TRY, el control se transfiere a la primera instrucción del bloque CATCH asociado.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. Si la instrucción END CATCH es la última instrucción de un procedimiento almacenado o desencadenador, el control se devuelve a la instrucción que llamó al procedimiento almacenado o activó el desencadenador.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.

Cuando finaliza el código del bloque CATCH, el control se transfiere a la instrucción inmediatamente posterior a la instrucción END CATCH.When the code in the CATCH block finishes, control passes to the statement immediately after the END CATCH statement. Los errores capturados por un bloque CATCH no se devuelven a la aplicación que realiza la llamada.Errors trapped by a CATCH block are not returned to the calling application. Si es necesario devolver cualquier parte de la información sobre el error a la aplicación, debe hacerlo el código del bloque CATCH a través de mecanismos como los conjuntos de resultados SELECT o las instrucciones RAISERROR y 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.

Las construcciones TRY…CATCH pueden estar anidadas.TRY...CATCH constructs can be nested. Un bloque TRY o un bloque CATCH puede contener construcciones TRY…CATCH anidadas.Either a TRY block or a CATCH block can contain nested TRY...CATCH constructs. Por ejemplo, un bloque CATCH puede contener una construcción TRY…CATCH insertada para controlar los errores detectados por el código de CATCH.For example, a CATCH block can contain an embedded TRY...CATCH construct to handle errors encountered by the CATCH code.

Los errores que se encuentren en un bloque CATCH se tratan como los errores generados en otros lugares.Errors encountered in a CATCH block are treated like errors generated anywhere else. Si el bloque CATCH contiene una construcción TRY…CATCH anidada, los errores del bloque TRY anidado transferirán el control al bloque CATCH anidado.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. Si no hay ninguna construcción TRY…CATCH anidada, el error se devuelve al autor de la llamada.If there is no nested TRY...CATCH construct, the error is passed back to the caller.

Las construcciones TRY…CATCH capturan los errores no controlados de los procedimientos almacenados o desencadenadores ejecutados por el código del bloque TRY.TRY...CATCH constructs catch unhandled errors from stored procedures or triggers executed by the code in the TRY block. Como alternativa, los procedimientos almacenados o desencadenadores pueden contener sus propias construcciones TRY…CATCH para controlar los errores generados por su código.Alternatively, the stored procedures or triggers can contain their own TRY...CATCH constructs to handle errors generated by their code. Por ejemplo, cuando un bloque TRY ejecuta un procedimiento almacenado y se produce un error en éste, el error se puede controlar de las formas siguientes: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:

  • Si el procedimiento almacenado no contiene su propia construcción TRY…CATCH, el error devuelve el control al bloque CATCH asociado al bloque TRY que contiene la instrucción 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.

  • Si el procedimiento almacenado contiene una construcción TRY…CATCH, el error transfiere el control al bloque CATCH del procedimiento almacenado.If the stored procedure contains a TRY...CATCH construct, the error transfers control to the CATCH block in the stored procedure. Cuando finaliza el código del bloque CATCH, el control se devuelve a la instrucción inmediatamente posterior a la instrucción EXECUTE que llamó al procedimiento almacenado.When the CATCH block code finishes, control is passed back to the statement immediately after the EXECUTE statement that called the stored procedure.

No se pueden utilizar instrucciones GOTO para entrar en un bloque TRY o CATCH.GOTO statements cannot be used to enter a TRY or CATCH block. Estas instrucciones se pueden utilizar para saltar a una etiqueta dentro del mismo bloque TRY o CATCH, o bien para salir de un bloque TRY o 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.

La construcción TRY…CATCH no se puede usar en una función definida por el usuario.The TRY...CATCH construct cannot be used in a user-defined function.

Recuperar información sobre erroresRetrieving Error Information

En el ámbito de un bloque CATCH, se pueden utilizar las siguientes funciones del sistema para obtener información acerca del error que provocó la ejecución del bloque 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() devuelve el número del error.ERROR_NUMBER() returns the number of the error.

  • ERROR_SEVERITY() devuelve la gravedad.ERROR_SEVERITY() returns the severity.

  • ERROR_STATE() devuelve el número de estado del error.ERROR_STATE() returns the error state number.

  • ERROR_PROCEDURE() devuelve el nombre del procedimiento almacenado o desencadenador donde se produjo el error.ERROR_PROCEDURE() returns the name of the stored procedure or trigger where the error occurred.

  • ERROR_LINE() devuelve el número de línea de la rutina que provocó el error.ERROR_LINE() returns the line number inside the routine that caused the error.

  • ERROR_MESSAGE() devuelve el texto completo del mensaje de error.ERROR_MESSAGE() returns the complete text of the error message. El texto incluye los valores proporcionados para los parámetros sustituibles, como las longitudes, nombres de objeto o tiempos.The text includes the values supplied for any substitutable parameters, such as lengths, object names, or times.

Estas funciones devuelven NULL si se las llama desde fuera del ámbito del bloque CATCH.These functions return NULL if they are called outside the scope of the CATCH block. Con ellas se puede recuperar información sobre los errores desde cualquier lugar dentro del ámbito del bloque CATCH.Error information can be retrieved by using these functions from anywhere within the scope of the CATCH block. Por ejemplo, en el siguiente script se muestra un procedimiento almacenado que contiene funciones de control de errores.For example, the following script shows a stored procedure that contains error-handling functions. Se llama al procedimiento almacenado en el bloque CATCH de una construcción TRY...CATCH y se devuelve información sobre el error.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;   

La función ERROR_* funciona también en un bloque CATCH de un procedimiento almacenado compilado de forma nativa.The ERROR_* functions also work in a CATCH block inside a natively compiled stored procedure.

Errores no afectados por una construcción TRY…CATCHErrors Unaffected by a TRY...CATCH Construct

Las construcciones TRY…CATCH no detectan las condiciones siguientes:TRY...CATCH constructs do not trap the following conditions:

  • Advertencias o mensajes informativos que tienen una gravedad 10 o inferior.Warnings or informational messages that have a severity of 10 or lower.

  • Errores que tienen la gravedad 20 o superior que detienen el procesamiento de las tareas de Motor de base de datos de SQL ServerSQL Server Database Engine en la sesión.Errors that have a severity of 20 or higher that stop the Motor de base de datos de SQL ServerSQL Server Database Engine task processing for the session. Si se produce un error con una gravedad 20 o superior y no se interrumpe la conexión de la base de datos, TRY…CATCH controlará el error.If an error occurs that has severity of 20 or higher and the database connection is not disrupted, TRY...CATCH will handle the error.

  • Atenciones, como solicitudes de interrupción de clientes o conexiones de cliente interrumpidas.Attentions, such as client-interrupt requests or broken client connections.

  • Cuando el administrador del sistema finaliza la sesión mediante la instrucción KILL.When the session is ended by a system administrator by using the KILL statement.

Un bloque CATCH no controla los siguientes tipos de errores cuando se producen en el mismo nivel de ejecución que la construcción 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:

  • Errores de compilación, como errores de sintaxis, que impiden la ejecución de un lote.Compile errors, such as syntax errors, that prevent a batch from running.

  • Errores que se producen durante la recompilación de instrucciones, como errores de resolución de nombres de objeto que se producen después de la compilación debido a una resolución de nombres diferida.Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.

  • Errores de resolución de nombres de objetoObject name resolution errors

Estos errores se devuelven al nivel de ejecución del lote, procedimiento almacenado o desencadenador.These errors are returned to the level that ran the batch, stored procedure, or trigger.

Si se produce un error durante la compilación o la recompilación de nivel de instrucción en un nivel de ejecución inferior (por ejemplo, al ejecutar sp_executesql o un procedimiento almacenado definido por el usuario) dentro del bloque TRY, el error se producirá en un nivel inferior a la construcción TRY…CATCH y lo controlará el bloque CATCH asociado.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.

En el ejemplo siguiente se muestra cómo la construcción SELECT no captura un error de resolución de nombre de objeto generado por una instrucción TRY...CATCH, sino que es el bloque CATCH el que lo captura cuando la misma instrucción SELECT se ejecuta dentro de un procedimiento almacenado.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  

El error no se captura y el control se transfiere fuera de la construcción TRY...CATCH, al siguiente nivel superior.The error is not caught and control passes out of the TRY...CATCH construct to the next higher level.

Al ejecutar la instrucción SELECT dentro de un procedimiento almacenado, el error se produce en un nivel inferior al bloque TRY.Running the SELECT statement inside a stored procedure will cause the error to occur at a level lower than the TRY block. La construcción TRY...CATCH controlará el error.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;  

Transacciones no confirmables y XACT_STATEUncommittable Transactions and XACT_STATE

Si un error generado en un bloque TRY hace que se invalide el estado de la transacción actual, la transacción se clasifica como una transacción no confirmable.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. Un error que normalmente termina una transacción fuera de un bloque TRY hace que la transacción no confirmable cuando se produce dentro de un bloque 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. Una transacción no confirmable solo puede realizar operaciones de lectura o ROLLBACK TRANSACTION.An uncommittable transaction can only perform read operations or a ROLLBACK TRANSACTION. La transacción no puede ejecutar ninguna instrucción Transact-SQLTransact-SQL que genere una operación de escritura o COMMIT TRANSACTION.The transaction cannot execute any Transact-SQLTransact-SQL statements that would generate a write operation or a COMMIT TRANSACTION. La función XACT_STATE devuelve el valor -1 si una transacción se ha clasificado como transacción no confirmable.The XACT_STATE function returns a value of -1 if a transaction has been classified as an uncommittable transaction. Cuando finaliza el lote, Motor de base de datosDatabase Engine revierte todas las transacciones activas no confirmables.When a batch finishes, the Motor de base de datosDatabase Engine rolls back any active uncommittable transactions. Si no se envió ningún mensaje de error cuando la transacción entró en un estado no confirmable, cuando finalice la ejecución del lote se enviará un mensaje de error a la aplicación 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. Esto indica que se ha detectado y revertido una transacción no confirmable.This indicates that an uncommittable transaction was detected and rolled back.

Para más información sobre las transacciones no confirmables y la función XACT_STATE, vea XACT_STATE (Transact-SQL).For more information about uncommittable transactions and the XACT_STATE function, see XACT_STATE (Transact-SQL).

EjemplosExamples

A.A. Uso de TRY…CATCHUsing TRY...CATCH

En el siguiente ejemplo se muestra una instrucción SELECT que generará un error de división por cero.The following example shows a SELECT statement that will generate a divide-by-zero error. El error hace que la ejecución salte al bloque CATCH asociado.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. Uso de TRY…CATCH en una transacciónUsing TRY...CATCH in a transaction

En este ejemplo se muestra cómo funciona un bloque TRY...CATCH dentro de una transacción.The following example shows how a TRY...CATCH block works inside a transaction. La instrucción del bloque TRY genera un error por infracción de restricción.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. Uso de TRY…CATCH con XACT_STATEUsing TRY...CATCH with XACT_STATE

En este ejemplo se muestra cómo utilizar la construcción TRY...CATCH para controlar los errores que se producen en una transacción.The following example shows how to use the TRY...CATCH construct to handle errors that occur inside a transaction. La función XACT_STATE determina si la transacción debe confirmarse o revertirse.The XACT_STATE function determines whether the transaction should be committed or rolled back. En este ejemplo SET XACT_ABORT es ON.In this example, SET XACT_ABORT is ON. Esto hace que la transacción sea no confirmable cuando se produce el error por infracción de restricción.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  

Ejemplos: Azure Synapse Analytics (SQL DW)Azure Synapse Analytics (SQL DW) y Almacenamiento de datos paralelosParallel Data WarehouseExamples: Azure Synapse Analytics (SQL DW)Azure Synapse Analytics (SQL DW) and Almacenamiento de datos paralelosParallel Data Warehouse

D.D. Uso de TRY…CATCHUsing TRY...CATCH

En el siguiente ejemplo se muestra una instrucción SELECT que generará un error de división por cero.The following example shows a SELECT statement that will generate a divide-by-zero error. El error hace que la ejecución salte al bloque CATCH asociado.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 tambiénSee Also

THROW (Transact-SQL) THROW (Transact-SQL)
Niveles de gravedad de error del motor de base de datos 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)