DECLARE CONDITION
DECLARE CONDITION asigna un nombre descriptivo a un código de error o SQLSTATE. Esto mejora la legibilidad del código al reemplazar números crípticos con nombres significativos.
Sintaxis
DECLARE nombre_condicion CONDITION FOR codigo_error;
DECLARE nombre_condicion CONDITION FOR SQLSTATE 'valor';Sin DECLARE CONDITION
-- El número 1062 no es autoexplicativo
DECLARE CONTINUE HANDLER FOR 1062
SET v_error = 'Duplicado';Con DECLARE CONDITION
-- Mucho más legible
DECLARE duplicado CONDITION FOR 1062;
DECLARE CONTINUE HANDLER FOR duplicado
SET v_error = 'Duplicado';Ejemplo completo
DELIMITER //
CREATE PROCEDURE insertar_cliente_seguro(
IN p_nombre VARCHAR(50),
IN p_apellidos VARCHAR(100),
IN p_email VARCHAR(100),
IN p_ciudad VARCHAR(50)
)
BEGIN
DECLARE registro_duplicado CONDITION FOR 1062;
DECLARE fk_invalida CONDITION FOR 1452;
DECLARE v_resultado VARCHAR(200);
DECLARE CONTINUE HANDLER FOR registro_duplicado
SET v_resultado = CONCAT('Error: el email ', p_email, ' ya está registrado');
DECLARE CONTINUE HANDLER FOR fk_invalida
SET v_resultado = 'Error: referencia a datos no existentes';
INSERT INTO clientes (nombre, apellidos, email, ciudad, telefono)
VALUES (p_nombre, p_apellidos, p_email, p_ciudad, '600000000');
IF v_resultado IS NULL THEN
SET v_resultado = CONCAT('Cliente ', p_nombre, ' insertado con ID ', LAST_INSERT_ID());
END IF;
SELECT v_resultado AS resultado;
END //
DELIMITER ;CALL insertar_cliente_seguro('María', 'García', 'maria.garcia@email.com', 'Madrid');| resultado |
|---|
| Error: el email maria.garcia@email.com ya está registrado |
Condiciones con SQLSTATE
DELIMITER //
CREATE PROCEDURE ejemplo_sqlstate()
BEGIN
-- Condiciones con nombre descriptivo
DECLARE restriccion_violada CONDITION FOR SQLSTATE '23000';
DECLARE tabla_no_existe CONDITION FOR SQLSTATE '42S02';
DECLARE v_error VARCHAR(200);
DECLARE CONTINUE HANDLER FOR restriccion_violada
SET v_error = 'Violación de restricción de integridad';
DECLARE CONTINUE HANDLER FOR tabla_no_existe
SET v_error = 'La tabla referenciada no existe';
-- Lógica...
SELECT COALESCE(v_error, 'Sin errores') AS estado;
END //
DELIMITER ;Códigos de error comunes
| Código MySQL | SQLSTATE | Nombre sugerido | Descripción |
|---|---|---|---|
| 1062 | 23000 | registro_duplicado | Entrada duplicada en índice único |
| 1452 | 23000 | fk_invalida | Violación de clave foránea al insertar |
| 1451 | 23000 | fk_referenciada | Violación de FK al eliminar padre |
| 1048 | 23000 | campo_nulo | Columna NOT NULL recibió NULL |
| 1146 | 42S02 | tabla_no_existe | La tabla no existe |
| 1054 | 42S22 | columna_no_existe | Columna desconocida |
| 1264 | 22003 | valor_fuera_rango | Valor fuera de rango para el tipo |
| 1406 | 22001 | dato_muy_largo | Dato demasiado largo para la columna |
Ejemplo práctico
DELIMITER //
CREATE PROCEDURE transferir_stock(
IN p_origen INT,
IN p_destino INT,
IN p_cantidad INT
)
BEGIN
DECLARE producto_no_encontrado CONDITION FOR SQLSTATE '02000';
DECLARE stock_insuficiente CONDITION FOR SQLSTATE '45000';
DECLARE v_stock_origen INT;
DECLARE v_error VARCHAR(200);
DECLARE v_exito BOOLEAN DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR producto_no_encontrado
SET v_error = 'Producto no encontrado';
DECLARE CONTINUE HANDLER FOR stock_insuficiente
SET v_error = 'Stock insuficiente para la transferencia';
-- Verificar origen
SELECT stock INTO v_stock_origen FROM productos WHERE id = p_origen;
IF v_stock_origen IS NULL THEN
SET v_error = 'Producto origen no encontrado';
ELSEIF v_stock_origen < p_cantidad THEN
SET v_error = CONCAT('Stock insuficiente. Disponible: ', v_stock_origen);
ELSE
UPDATE productos SET stock = stock - p_cantidad WHERE id = p_origen;
UPDATE productos SET stock = stock + p_cantidad WHERE id = p_destino;
SET v_exito = TRUE;
END IF;
IF v_exito THEN
SELECT 'Transferencia completada' AS resultado, p_cantidad AS unidades;
ELSE
SELECT v_error AS resultado;
END IF;
END //
DELIMITER ;Limpieza
DROP PROCEDURE IF EXISTS insertar_cliente_seguro;
DROP PROCEDURE IF EXISTS ejemplo_sqlstate;
DROP PROCEDURE IF EXISTS transferir_stock;En el siguiente artículo veremos SIGNAL para lanzar errores personalizados desde procedimientos.
Escrito por Eduardo Lázaro
