El tratamiento de excepciones en MySQL permite manejar errores dentro de procedimientos almacenados, funciones y triggers para evitar que una consulta falle sin control.
✅ Manejo de errores con DECLARE HANDLER
✅ Captura de errores específicos (SQLEXCEPTION
, SQLWARNING
, NOT FOUND
)
✅ Uso de SIGNAL
y RESIGNAL
para generar errores personalizados
DECLARE HANDLER
)En MySQL, se pueden capturar errores con DECLARE HANDLER
y ejecutar acciones específicas cuando ocurre un error.
🔹 Sintaxis básica:
DECLARE tipo_manejador HANDLER FOR condición SQL
BEGIN
-- Código que se ejecuta cuando ocurre el error
END;
Tipo de Excepción | Descripción |
---|---|
SQLEXCEPTION |
Captura cualquier error SQL |
SQLWARNING |
Captura advertencias SQL |
NOT FOUND |
Se usa para cursores (cuando no hay más filas) |
SQLEXCEPTION
)DELIMITER $$
CREATE PROCEDURE InsertarCliente(IN nombre VARCHAR(100), IN email VARCHAR(100))
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- En caso de error, muestra un mensaje y revierte cambios
ROLLBACK;
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error al insertar cliente';
END;
START TRANSACTION;
INSERT INTO clientes (nombre, email) VALUES (nombre, email);
COMMIT;
END $$
DELIMITER ;
🔹 Explicación:
INSERT
falla (por clave duplicada o restricción), se ejecuta el HANDLER
.ROLLBACK
.SIGNAL
lanza un error personalizado con el mensaje 'Error al insertar cliente'
.SQLSTATE
)Cada error en MySQL tiene un código SQLSTATE
(5 caracteres). Se puede capturar un error específico con DECLARE HANDLER FOR SQLSTATE 'codigo'
.
🔹 Ejemplo: Capturar error de clave duplicada (SQLSTATE '23000'
)
DELIMITER $$
CREATE PROCEDURE InsertarProducto(IN id_producto INT, IN nombre VARCHAR(100))
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000'
BEGIN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'El ID del producto ya existe';
END;
INSERT INTO productos (id_producto, nombre) VALUES (id_producto, nombre);
END $$
DELIMITER ;
✅ Si intentas insertar un producto con un id_producto
duplicado, MySQL devolverá el mensaje 'El ID del producto ya existe'
en lugar de un error genérico.
SIGNAL
para Lanzar Errores PersonalizadosSIGNAL
permite generar errores personalizados para detener la ejecución y devolver un mensaje claro al usuario.
🔹 Ejemplo: Validar que el saldo de una cuenta no sea negativo
DELIMITER $$
CREATE PROCEDURE RetirarDinero(IN id_cuenta INT, IN monto DECIMAL(10,2))
BEGIN
DECLARE saldo_actual DECIMAL(10,2);
-- Obtener saldo
SELECT saldo INTO saldo_actual FROM cuentas WHERE id_cuenta = id_cuenta;
-- Validar saldo suficiente
IF saldo_actual < monto THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Saldo insuficiente';
ELSE
UPDATE cuentas SET saldo = saldo - monto WHERE id_cuenta = id_cuenta;
END IF;
END $$
DELIMITER ;
✅ Si el usuario intenta retirar más dinero del que tiene, MySQL devolverá 'Saldo insuficiente'
.
RESIGNAL
para Reenviar un ErrorRESIGNAL
permite capturar un error, procesarlo y reenviarlo para que sea manejado por otro nivel.
🔹 Ejemplo: Capturar un error y reenviarlo con otro mensaje
DELIMITER $$
CREATE PROCEDURE EliminarPedido(IN id_pedido INT)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- Captura el error y lo reenviamos con otro mensaje
RESIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error al eliminar el pedido';
END;
DELETE FROM pedidos WHERE id_pedido = id_pedido;
END $$
DELIMITER ;
✅ Si el DELETE
falla, en lugar de mostrar el error original, se muestra 'Error al eliminar el pedido'
.
NOT FOUND
)Si usas cursores para recorrer registros, puedes capturar el error cuando no hay más filas (NOT FOUND
).
🔹 Ejemplo: Recorrer pedidos y sumar total de ventas
DELIMITER $$
CREATE PROCEDURE CalcularTotalVentas()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE total DECIMAL(10,2) DEFAULT 0;
DECLARE precio DECIMAL(10,2);
DECLARE cursor_pedidos CURSOR FOR SELECT precio FROM pedidos;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cursor_pedidos;
leer_pedidos: LOOP
FETCH cursor_pedidos INTO precio;
IF done THEN
LEAVE leer_pedidos;
END IF;
SET total = total + precio;
END LOOP;
CLOSE cursor_pedidos;
SELECT total AS Total_Ventas;
END $$
DELIMITER ;
✅ El HANDLER FOR NOT FOUND
evita un error cuando se terminan los registros del cursor.
✅ Siempre usa DECLARE HANDLER
en procedimientos críticos para evitar errores inesperados.
✅ Usa SIGNAL
para generar mensajes de error personalizados y hacer más claro el problema.
✅ Utiliza RESIGNAL
si necesitas capturar y reenviar errores a otro nivel.
✅ Si usas cursores, maneja NOT FOUND
para evitar errores al recorrer registros.
✅ Prueba los procedimientos con datos de prueba antes de usarlos en producción.