Disparadores PostgreSQL AFTER
Los desencadenantes en PostgreSQL son funciones que se ejecutan automáticamente en respuesta a eventos específicos en una tabla, como INSERTAR, ACTUALIZAR o ELIMINAR. Un desencadenante AFTER se ejecuta después de que haya finalizado el evento desencadenante, lo que le permite acceder al estado final de los datos.
Utilización
Los desencadenantes DESPUÉS se utilizan cuando necesitas realizar acciones después de un evento de modificación de datos, asegurando que cualquier operación dependiente se produzca sólo después de que el evento inicial se haya completado con éxito. Se definen mediante la declaración CREATE TRIGGER.
CREATE TRIGGER trigger_name
AFTER event [OR event ...]
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
En esta sintaxis, AFTER event especifica el evento (INSERT, UPDATE, DELETE) que activa el desencadenador, y function_name() es la función a ejecutar tras el evento.
Ejemplos
1. Activador básico AFTER INSERT
CREATE OR REPLACE FUNCTION log_new_user()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO user_logs(user_id, action, log_time)
VALUES (NEW.id, 'User Created', NOW());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER after_user_insert
AFTER INSERT ON users
FOR EACH ROW
EXECUTE FUNCTION log_new_user();
Este ejemplo registra la entrada de un nuevo usuario en user_logs tras una inserción en la tabla users.
2. Activador AFTER UPDATE
CREATE OR REPLACE FUNCTION update_inventory_log()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO inventory_logs(product_id, change, log_time)
VALUES (NEW.product_id, NEW.quantity - OLD.quantity, NOW());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER after_inventory_update
AFTER UPDATE ON inventory
FOR EACH ROW
EXECUTE FUNCTION update_inventory_log();
Este activador registra el cambio de cantidad de un producto en inventory_logs después de que se actualice la tabla inventory.
3. Activador AFTER DELETE con lógica condicional
CREATE OR REPLACE FUNCTION log_deleted_order()
RETURNS TRIGGER AS $$
BEGIN
IF OLD.status = 'completed' THEN
INSERT INTO order_logs(order_id, action, log_time)
VALUES (OLD.id, 'Completed Order Deleted', NOW());
END IF;
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER after_order_delete
AFTER DELETE ON orders
FOR EACH ROW
EXECUTE FUNCTION log_deleted_order();
Este ejemplo registra la eliminación de pedidos completados de la tabla orders, sólo si el estado del pedido era "completado".
Consejos y buenas prácticas
- Utiliza activadores AFTER para las operaciones dependientes. Aplícalos cuando las acciones posteriores dependan de la finalización de la transacción original.
- Mantén la eficacia de las funciones de activación. Asegúrate de que la función ejecutada por el activador está optimizada para evitar ralentizar las transacciones.
- Evita la lógica compleja. Simplifica la lógica dentro de los activadores para mantener la claridad y la facilidad de mantenimiento.
- Prueba a fondo los activadores. Asegúrate de que los activadores no afectan involuntariamente a la lógica de la aplicación, probándolos exhaustivamente.
- Documenta el comportamiento desencadenante. Mantén una documentación clara de para qué está diseñado cada activador, especialmente en las aplicaciones más grandes.
- Controla el impacto en el rendimiento. Utiliza herramientas de registro o supervisión para hacer un seguimiento del impacto en el rendimiento de los activadores en las bases de datos de producción.
- Comprende las interacciones de las transacciones. Los desencadenantes AFTER forman parte de la transacción; si se produce un error en la función desencadenante, puede revertirse toda la transacción.
- Ten en cuenta las limitaciones. Ten en cuenta los posibles conflictos con restricciones de clave foránea o acciones en cascada cuando utilices activadores AFTER.
- Gestiona el ciclo de vida del activador. Saber desactivar o soltar un disparador cuando ya no se necesita utilizando
ALTER TABLEoDROP TRIGGER.