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.

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;
idproducto_idnombre_productoprecio_anteriorprecio_nuevodiferenciaporcentaje_cambio
11iPhone 15 Pro1299.991399.99100.007.69
-- Restaurar
UPDATE productos SET precio = 1299.99 WHERE id = 1;

Historial de estados

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ísticaBEFORE UPDATEAFTER UPDATE
MomentoAntes del cambioDespués del cambio
Modificar NEWNo
Cancelar operaciónSí, con SIGNALNo, ya se actualizó
Uso principalValidaciónAuditoría, sincronización
Datos consistentesNEW puede ser modificadoOLD 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