La declaración en SQL try catch se usa para manejar los errores que ocurren en la ejecución de una declaración T-SQL. Proporciona una forma de capturar y procesar errores de manera controlada, en lugar de que la consulta o el procedimiento almacenado falle abruptamente. Try Catch lo ayuda a manejar los errores de consulta de manera efectiva.
Sintaxis de la declaración en SQL TRY CATCH
La sintaxis de SQL Server Try Catch es:
BEGIN TRY
--Sentencias T-SQL que pueden causar un error
END TRY
BEGIN CATCH
--Código para manejar el error
END CATCH
El bloque try contiene las declaraciones T-SQL que pueden causar un error. Es en el bloque catch, donde el error puede manejarse y procesarse. Sin embargo, el bloque SQL try CATCH no manejara los errores de compilación y sintaxis en la programación.
Dentro del bloque Catch, utilice la siguiente función del sistema para obtener la información sobre un error.
- ERROR_MESSAGE(): Devuelve la descripción completa de un error. Por ejemplo, desbordamiento aritmético, etc.
- ERROR_LINE(): Devuelve en qué línea ocurre un error.
- ERROR_NUMBER(): Devuelve el número de Error.
- ERROR_SEVERITY(): Muestra la gravedad de un error.
- ERROR_PROCEDURE(): Devuelve el nombre del Trigger o Procedimiento Almacenado sobre el que se produce el error.
- ERROR_STATE() : Retorna el estado de un error en SQL Server.
SQL TRY CATCH Ejemplo
En este ejemplo, mostramos cómo funcionará realmente el proceso. Aquí, estamos usando las diferentes declaraciones de impresión para mostrar el inicio y el FIN de SQL TRY Catch.
DECLARE @Number TINYINT, @Result TINYINT BEGIN TRY SET @Number = 255; SET @Result = @Number + 1; SELECT @Number AS Número, @Result AS Resultado; END TRY BEGIN CATCH PRINT N'Error Mensage = ' + ERROR_MESSAGE() PRINT N'Número Error = ' + CAST(ERROR_NUMBER() AS VARCHAR) PRINT N'Línea de error = ' + CAST(ERROR_LINE() AS VARCHAR) PRINT N'Error_Severidad = ' + CAST(ERROR_SEVERITY() AS VARCHAR) PRINT N'Error_Estado = ' + CAST(ERROR_STATE() AS VARCHAR) END CATCH
De la captura de pantalla anterior, vea que solo imprime las declaraciones del bloque SQL CATCH.
ANÁLISIS
Dentro de la declaración en SQL try catch del ejemplo anterior, intentamos capturar el ejemplo de manejo de errores. Primero, declaramos dos variables.
DECLARE @Number TINYINT, @Result TINYINT
Luego, dentro del bloque TRY, asignamos 255 a la variable Número y realizamos la suma para la variable resultado.
SET @Number = 255;
SET @Result = @Number + 1;
SELECT @Number AS Número, @Result AS Resultado;
Como todos sabemos, ese minúsculo int que contiene hasta 255 significa desbordamiento. Entonces, saldrá del bloque TRY y ejecutará la declaración dentro de nuestro bloque CATCH, que es:
PRINT N'Error Mensage = ' + ERROR_MESSAGE() PRINT N'Número Error = ' + CAST(ERROR_NUMBER() AS VARCHAR) PRINT N'Línea de error = ' + CAST(ERROR_LINE() AS VARCHAR) PRINT N'Error_Severidad = ' + CAST(ERROR_SEVERITY() AS VARCHAR) PRINT N'Error_Estado = ' + CAST(ERROR_STATE() AS VARCHAR)
Si observa la captura de pantalla del ejemplo anterior, aunque tenemos la declaración de impresión al final del bloque TRY, el controlador omitió esa declaración. Es porque una vez que entra en SET @Result = @Number + 1; el control saldrá del bloque TRY e inmediatamente entrará en el bloque Catch.
Sin embargo, si agregamos 240 a la variable, no habrá desbordamiento y no se imprimirá el error, ver resultado:
Número | Resultado --------------- 240 | 241
Manejo de errores de valor nulo con SQL try catch
Para entender este ejemplo, primero vamos a crear la tabla EMPLEADOS en SQL Server e inserte algunos registros en ella.
CREATE TABLE EMPLEADOS ( EMPLE_ID INT PRIMARY KEY IDENTITY(1,1), NOMBRE NVARCHAR(50) NOT NULL, APELLIDO NVARCHAR(50) NOT NULL, EMAIL NVARCHAR(100) NOT NULL, TELEFONO NVARCHAR(20) NOT NULL); -- Insertar algunos registros en la tabla. INSERT INTO EMPLEADOS (NOMBRE, APELLIDO, EMAIL, TELEFONO) VALUES ('PEDRO', 'RODRIGUEZ', 'pedro32@example.com', '555-536-4558'), ('ROSA', 'CARASCO', 'rosacara@example.com', '555-518-1856'), ('JOSE', 'PEREZ', 'joseperez14@example.com', '555-525-2557'), ('ANA', 'MARRERA', 'anamar@example.com', '555-525-2547'), ('RAMON', 'FERNANDEZ', 'ramonfer@example.com', '555-525-2587');
Ahora, intentemos usar la instrucción SQL try catch para manejar los errores de valor nulo, que pueden ocurrir cuando intentamos insertar un valor nulo. El siguiente código demuestra cómo usar la declaración try-catch para manejar este tipo de error:
BEGIN TRY INSERT INTO EMPLEADOS (NOMBRE, APELLIDO, EMAIL, TELEFONO) VALUES ('ELENA', 'RODRIGUEZ', NULL, '555-455-5451') END TRY BEGIN CATCH PRINT 'Error: no se puede insertar un valor nulo en la columna Email.' END CATCH
Producción:
Transacciones con instrucción SQL try catch
El siguiente es un ejemplo completo del uso de una instrucción SQL try catch dentro de una transacción en SQL Server:
BEGIN TRANSACTION BEGIN TRY UPDATE EMPLEADOS SET TELEFONO= '555-545-4215' WHERE EMPLE_ID = 2; -- Esta declaración generará un error UPDATE EMPLEADOS SET Email = NULL WHERE EMPLE_ID = 3; END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumero, ERROR_STATE() AS Errorestado, ERROR_SEVERITY() AS ErrorSeveridad, ERROR_LINE() AS ErrorLinea, ERROR_PROCEDURE() AS ErrorProcedimiento, ERROR_MESSAGE() AS ErrorMessage; -- Revertir la transacción ROLLBACK TRANSACTION; END CATCH; -- Si no hubo errores, confirme la transacción. IF @@TRANCOUNT > 0 COMMIT TRANSACTION;
En este ejemplo, una transacción se inicia con la instrucción BEGIN TRANSACTION. Dentro de la transacción, hay una instrucción SQL try catch. El bloque try contiene dos sentencias UPDATE. La primera declaración actualiza el número de teléfono del cliente con EMPLE_ID 2, mientras que la segunda declaración genera un error al intentar actualizar una dirección de correo electrónico no válida.
El bloque catch se usa para manejar cualquier error que ocurra en el bloque try. Si ocurre un error, se ejecutará el bloque catch y se mostrará información sobre el error mediante las funciones del sistema ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_LINE(), ERROR_PROCEDURE()y ERROR_MESSAGE().
Después de detectar el error, la transacción se revierte utilizando la declaración ROLLBACK TRANSACTION, por lo que cualquier cambio realizado dentro de la transacción se descarta. Si no hubo errores en el bloque de prueba, la transacción se confirmará utilizando la declaración COMMIT TRANSACTION. La variable @@TRANCOUNT se usa para verificar si una transacción aún está activa, y la transacción se confirmará solo si es mayor que cero.
Manejo de excepciones en procedimientos almacenados
Es esencial manejar las excepciones en los procedimientos almacenados para evitar que los errores afecten su aplicación o base de datos. La construcción SQL TRY CATCH se usa para manejar excepciones en procedimientos almacenados. He aquí un ejemplo de cómo usar esta declaración:
CREATE PROCEDURE Insertar_empleado NOMBRE NVARCHAR(50) = NOT NULL, APELLIDO NVARCHAR(50) = NOT NULL, EMAIL NVARCHAR(100) =NOT NULL, TELEFONO NVARCHAR(20)= NOT NULL AS BEGIN TRY INSERT INTO EMPLEADOS (NOMBRE, APELLIDO, EMAIL, TELEFONO) VALUES (@NOMBRE='ELENA', @APELLIDO='RODRIGUEZ', EMAIL='elena25@emplo.com ', @TELEFONO=' ') END TRY BEGIN CATCH PRINT 'Error: Al insertar la columna Email.' END CATCH END GO
En este ejemplo, intentamos insertar el campo TELEFONO nulo es decir sin datos, lo que resulta en un error. El bloque SQL TRY CATCH detecta el error y devuelve el mensaje de error en vez de bloquear el procedimiento almacenado.
Conclusión
Cuando se utiliza un bloque TRY CATCH en SQL, deben tener en presente:
- Identificar qué partes del código SQL pueden lanzar excepciones y rodearlas con bloques TRY…CATCH.
- Asegurarse de que los errores se manejen adecuadamente y no se dejen sin tratar, lo que podría provocar una falla en la aplicación o un comportamiento inesperado.
- Evitar el uso excesivo de bloques TRY…CATCH, ya que esto puede dificultar la lectura y la comprensión del código.
En resumen, al utilizar bloques TRY…CATCH en SQL Server, es importante identificar las partes del código que pueden lanzar excepciones, planificar cómo se manejarán esas excepciones y utilizar la información detallada proporcionada por la función ERROR_MESSAGE() para ayudar en la solución de problemas y la depuración del código.