Gestión de errores en Transact SQL
La gestión de errores, es un aspecto fundamental en el manejo de código Transact SQL, que nos permite controlar nuestro flujo de código y detectar problemas y errores que nos facilitan su resolución o información.
A través del manejo de excepciones, podemos tener un control total sobre nuestra aplicación y detectar las casuísticas que provocan interrupciones en nuestro código.
Existen estructuras de control de flujo especialmente diseñadas para la gestión de errores. En esta sección nos centraremos en el TRY...CATCH y el THROW.
TRY…CATCH
TRY…CATCH es una estructura de control de flujo que nos permite detectar y atrapar errores. El funcionamiento esencial es simple:
-
TRY: Encierra una serie de instrucciones Transact SQL que intentarán ejecutarse.
-
CATCH: Recoge cualquier error que se produzca en el
TRY, ejecutándose las sentencias propias de este bloqueCATCH, que generalmente estarán destinadas a proporcionar información acerca del error producido.
En definitiva, si todo va bien, el código perteneciente a la cláusula CATCH no se ejecuta. Sin embargo, si durante la ejecución del TRY se produce algún error, el código saltará al CATCH para atraparlo y tratarlo.
En cuanto a la sintaxis, es la siguiente:
BEGIN TRY
[codigo]
END TRY
BEGIN CATCH
[codigo]
END CATCH
Existen algunas consideraciones ha tener en cuenta acerca del TRY...CATCH:
-
Puede utilizarse dentro de procedimientos almacenados.
-
Las sentencias
TRY...CATCHpueden anidarse. -
TRY debe ir siempre acompañado inmediatamente después de su bloque
CATCHcorrespondiente. Cualquier instrucción entreEND TRYyBEGIN CATCH, causará un error sintáctico. -
No permite englobar varios lotes. Por ejemplo, no podrá contener más de un bloque
BEGIN...ENDni construccionesIF...ELSE.
Funciones ERROR
Existen una serie de funciones encargadas de devolver información acerca de los errores producidos, muy utilizadas a menudo dentro del bloque CATCH.
-
ERROR_NUMBER(): devuelve el número del error.
-
ERROR_SEVERITY(): devuelve la gravedad del error.
-
ERROR_STATE(): devuelve el número de estado de error.
-
ERROR_PROCEDURE(): devuelve el nombre del procedimiento almacenado o disparador donde ocurrió el error.
-
ERROR_LINE(): devuelve el número de línea dentro de la rutina que provocó el error.
-
ERROR_MESSAGE(): devuelve el texto completo del mensaje de error.
Ejemplo
Para ejemplificar el funcionamiento de TRY...CATCH de manera sencilla, procedemos a intentar dividir un número entre cero dentro de un bloque TRY...CATCH para capturar y devolver información del error:
BEGIN TRY
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
| ErrorNumber | ErrorSeverity | ErrorState | ErrorProcedure | ErrorLine | ErrorMessage |
|---|---|---|---|---|---|
| 8134 | 16 | 1 | NULL | 2 | Error de división entre cero. |
THROW
THROW nos permite generar nuestras propias excepciones y devolverlas en el bloque CATCH de una construcción TRY...CATCH. De esta manera, podremos manejar una gestión de errores personalizada.
La sintaxis es la siguiente:
THROW (error_number | variable,
message | variable ,
state | variable )
Argumentos THROW
Como vemos en su sintaxis, la instrucción THROW utiliza tres argumentos importantes en su declaración:
-
error_number: Indica el número del error. Será de tipo de dato
INTy su valor deberá estar comprendido entre 50000 y 2147483647 (ambos incluidos) -
message: devuelve el texto completo del mensaje de error que especifiquemos
-
state: devuelve el número de estado de error. Será de tipo
TINYINTcon un valor comprendido entre 0 y 255 (ambos incluidos)
Ejemplo
Para ejemplificar el funcionamiento de THROW de manera sencilla, procedemos a intentar dividir un número entre cero dentro de un bloque TRY...CATCH para capturar y devolver la información personalizada del error generado:
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
THROW 50100, 'La operación matemática es errónea.',1;
END CATCH;
GO
Msg 50100, Level 16, State 1, Line 5 La operación matemática es errónea.