AFTER UPDATE
Un trigger AFTER UPDATE se ejecuta después de que una fila ha sido modificada exitosamente. Tiene acceso a OLD y NEW pero no puede modificar ninguno. Es ideal para auditoría y sincronización. Para validar o transformar datos antes de la modificación, usa BEFORE UPDATE.
Sintaxis
DELIMITER //
CREATE TRIGGER nombre_trigger
AFTER UPDATE ON nombre_tabla
FOR EACH ROW
BEGIN
-- OLD.columna = valor anterior
-- NEW.columna = valor nuevo
-- No se pueden modificar
END //
DELIMITER ;Auditoría de cambios de precio
CREATE TABLE IF NOT EXISTS auditoria_precios (
id INT AUTO_INCREMENT PRIMARY KEY,
producto_id INT,
nombre_producto VARCHAR(100),
precio_anterior DECIMAL(10,2),
precio_nuevo DECIMAL(10,2),
diferencia DECIMAL(10,2),
porcentaje_cambio DECIMAL(5,2),
usuario VARCHAR(100),
fecha DATETIME DEFAULT NOW()
);DELIMITER //
CREATE TRIGGER tr_audit_precio
AFTER UPDATE ON productos
FOR EACH ROW
BEGIN
IF OLD.precio != NEW.precio THEN
INSERT INTO auditoria_precios
(producto_id, nombre_producto, precio_anterior, precio_nuevo,
diferencia, porcentaje_cambio, usuario)
VALUES
(NEW.id, NEW.nombre, OLD.precio, NEW.precio,
NEW.precio - OLD.precio,
ROUND((NEW.precio - OLD.precio) / OLD.precio * 100, 2),
USER());
END IF;
END //
DELIMITER ;UPDATE productos SET precio = 1399.99 WHERE id = 1;
SELECT * FROM auditoria_precios;| id | producto_id | nombre_producto | precio_anterior | precio_nuevo | diferencia | porcentaje_cambio |
|---|---|---|---|---|---|---|
| 1 | 1 | iPhone 15 Pro | 1299.99 | 1399.99 | 100.00 | 7.69 |
-- Restaurar
UPDATE productos SET precio = 1299.99 WHERE id = 1;Historial de estados
Registrar cada cambio de estado en una tabla de historial es un patrón habitual de auditoría. Este tipo de registro es especialmente útil cuando se combina con transacciones, ya que el INSERT en la tabla de historial y el UPDATE original se revierten juntos si hay un error:
CREATE TABLE IF NOT EXISTS historial_pedidos (
id INT AUTO_INCREMENT PRIMARY KEY,
pedido_id INT,
estado_anterior VARCHAR(20),
estado_nuevo VARCHAR(20),
fecha DATETIME DEFAULT NOW()
);DELIMITER //
CREATE TRIGGER tr_pedidos_historial
AFTER UPDATE ON pedidos
FOR EACH ROW
BEGIN
IF OLD.estado != NEW.estado THEN
INSERT INTO historial_pedidos (pedido_id, estado_anterior, estado_nuevo)
VALUES (NEW.id, OLD.estado, NEW.estado);
END IF;
END //
DELIMITER ;AFTER UPDATE vs BEFORE UPDATE
| Característica | BEFORE UPDATE | AFTER UPDATE |
|---|---|---|
| Momento | Antes del cambio | Después del cambio |
| Modificar NEW | Sí | No |
| Cancelar operación | Sí, con SIGNAL | No, ya se actualizó |
| Uso principal | Validación | Auditoría, sincronización |
| Datos consistentes | NEW puede ser modificado | OLD y NEW son definitivos |
Limpieza
DROP TRIGGER IF EXISTS tr_audit_precio;
DROP TRIGGER IF EXISTS tr_pedidos_historial;
DROP TABLE IF EXISTS auditoria_precios;
DROP TABLE IF EXISTS historial_pedidos;En el siguiente artículo veremos los triggers BEFORE DELETE.
Escrito por Eduardo Lázaro
