Disparadores a nivel de fila PostgreSQL
Los desencadenantes en PostgreSQL son procedimientos que se ejecutan automáticamente en respuesta a determinados eventos en una tabla o vista concreta. Los desencadenantes a nivel de fila se ejecutan específicamente para cada fila afectada por un evento como un `INSERT`, `UPDATE` o `DELETE`.
Utilización
Los activadores a nivel de fila se utilizan para aplicar reglas de negocio, validar datos o mantener un registro personalizado a nivel de fila. Se definen para realizar acciones específicas cada vez que se modifica una fila de una manera determinada.
sql
CREATE TRIGGER trigger_name
AFTER | BEFORE INSERT | UPDATE | DELETE
ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();
En esta sintaxis, `POR CADA FILA` especifica que el activador se disparará por cada fila afectada, y `EXECUTE FUNCTION` llama a la función que contiene la lógica a ejecutar.
Ejemplos
1. Activador básico de inserción
sql
CREATE OR REPLACE FUNCTION log_new_inserts()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_log (table_name, operation, timestamp)
VALUES (TG_TABLE_NAME, 'INSERT', now());
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_insert
AFTER INSERT ON employees
FOR EACH ROW
EXECUTE FUNCTION log_new_inserts();
Este ejemplo crea un activador que registra cada nueva operación `INSERT` en la tabla `employees` en una tabla `audit_log`.
2. Actualizar activador con condición
sql
CREATE OR REPLACE FUNCTION check_salary_update()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.salary < OLD.salary THEN
RAISE EXCEPTION 'Salary cannot be decreased!';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER salary_check
BEFORE UPDATE ON employees
FOR EACH ROW
EXECUTE FUNCTION check_salary_update();
Aquí, un activador evita las reducciones salariales lanzando una excepción si el nuevo salario es menor que el anterior durante una "ACTUALIZACIÓN".
3. Eliminar activador con registro
sql
CREATE OR REPLACE FUNCTION log_delete()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO delete_log (table_name, deleted_row_id, timestamp)
VALUES (TG_TABLE_NAME, OLD.id, now());
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER log_delete
AFTER DELETE ON orders
FOR EACH ROW
EXECUTE FUNCTION log_delete();
Este ejemplo registra los detalles de las filas eliminadas de la tabla `orders` en un `delete_log` con fines de auditoría. Asume que `OLD.id` corresponde a la clave primaria o a un identificador único de la fila.
Consejos y buenas prácticas
- Utiliza los activadores con criterio. El uso excesivo de activadores puede dar lugar a sistemas complejos y difíciles de depurar.
- Garantiza la atomicidad. La función desencadenante debe ser atómica e idempotente para mantener la integridad de los datos.
- Considera el impacto en el rendimiento. Los desencadenantes añaden sobrecarga y se ejecutan de forma sincrónica con la operación desencadenante; asegúrate de que su rendimiento está optimizado para evitar ralentizar las operaciones de la base de datos.
- Prueba a fondo los activadores. Garantizar pruebas exhaustivas para validar que los activadores se comportan correctamente en todos los escenarios.
- Documenta la lógica de activación. Documenta claramente la finalidad y la lógica de cada activador para futuras referencias y mantenimiento.
Información adicional
Variables especiales: Los activadores PostgreSQL utilizan variables especiales como `TG_TABLE_NAME`, `NEW` y `OLD` para proporcionar contexto. TG_TABLE_NAME" se refiere al nombre de la tabla a la que está asociado el activador, "NEW" contiene los datos de la nueva fila para las operaciones "INSERT" o "UPDATE", y "OLD" contiene los datos de la fila existente para las operaciones "UPDATE" o "DEELETE".