BEFORE DELETE
Un trigger BEFORE DELETE se ejecuta antes de que una fila sea eliminada de la tabla. Tiene acceso a OLD con los valores que se van a eliminar. Puede cancelar la eliminación con SIGNAL.
Sintaxis
DELIMITER //
CREATE TRIGGER nombre_trigger
BEFORE DELETE ON nombre_tabla
FOR EACH ROW
BEGIN
-- OLD.columna contiene los valores que se van a eliminar
-- NEW no está disponible en DELETE
END //
DELIMITER ;Prevenir eliminaciones
DELIMITER //
CREATE TRIGGER tr_productos_before_delete
BEFORE DELETE ON productos
FOR EACH ROW
BEGIN
DECLARE v_pedidos INT;
SELECT COUNT(*) INTO v_pedidos
FROM detalle_pedidos WHERE producto_id = OLD.id;
IF v_pedidos > 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No se puede eliminar un producto con pedidos asociados';
END IF;
END //
DELIMITER ;-- Esto falla si el producto tiene pedidos
-- DELETE FROM productos WHERE id = 1;
-- Error: No se puede eliminar un producto con pedidos asociadosArchivar antes de eliminar
CREATE TABLE IF NOT EXISTS productos_archivados (
id INT,
nombre VARCHAR(100),
precio DECIMAL(10,2),
stock INT,
categoria_id INT,
fecha_archivado DATETIME DEFAULT NOW()
);DELIMITER //
CREATE TRIGGER tr_archivar_producto
BEFORE DELETE ON productos
FOR EACH ROW
BEGIN
INSERT INTO productos_archivados (id, nombre, precio, stock, categoria_id)
VALUES (OLD.id, OLD.nombre, OLD.precio, OLD.stock, OLD.categoria_id);
END //
DELIMITER ;Soft delete con trigger
En lugar de eliminar físicamente, puedes forzar el uso de desactivación:
DELIMITER //
CREATE TRIGGER tr_soft_delete
BEFORE DELETE ON productos
FOR EACH ROW
BEGIN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Use UPDATE SET activo = FALSE en lugar de DELETE';
END //
DELIMITER ;Validar relaciones
DELIMITER //
CREATE TRIGGER tr_clientes_before_delete
BEFORE DELETE ON clientes
FOR EACH ROW
BEGIN
DECLARE v_pedidos_activos INT;
SELECT COUNT(*) INTO v_pedidos_activos
FROM pedidos
WHERE cliente_id = OLD.id
AND estado IN ('pendiente', 'enviado');
IF v_pedidos_activos > 0 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No se puede eliminar un cliente con pedidos activos';
END IF;
END //
DELIMITER ;Limpieza
DROP TRIGGER IF EXISTS tr_productos_before_delete;
DROP TRIGGER IF EXISTS tr_archivar_producto;
DROP TRIGGER IF EXISTS tr_soft_delete;
DROP TRIGGER IF EXISTS tr_clientes_before_delete;
DROP TABLE IF EXISTS productos_archivados;En el siguiente artículo veremos los triggers AFTER DELETE.
Escrito por Eduardo Lázaro
