Ir al contenido principal
Documentos
Funciones de cadenaDesencadenaBases de datosFunciones JSONFunciones matemáticasFunciones de fechaÍndicesSintaxis básicaGestión de Tablas y Esquemas

Disparadores a nivel de sentencia PostgreSQL

Los disparadores en PostgreSQL son procedimientos especiales que se ejecutan o disparan automáticamente cuando se producen determinados eventos en una tabla de la base de datos. Los disparadores a nivel de sentencia se ejecutan una vez por sentencia SQL, independientemente del número de filas afectadas por la sentencia.

Utilización
Los disparadores a nivel de sentencia se utilizan para aplicar reglas de negocio, validar entradas o mantener registros de auditoría cuando una sentencia afecta a cualquier número de filas. Se definen para actuar antes o después de las operaciones `INSERT`, `UPDATE` o `DELETE` en una tabla.

sql
CREATE TRIGGER trigger_name
{ BEFORE | AFTER } { INSERT | UPDATE | DELETE }
ON table_name
FOR EACH STATEMENT
EXECUTE PROCEDURE function_name();

En esta sintaxis, "PARA CADA DECLARACIÓN" especifica que el activador debe dispararse una vez por cada declaración, y "EJECUTAR PROCEDIMIENTO" define la función que debe invocarse. Ten en cuenta que los activadores a nivel de sentencia no tienen acceso a los valores de fila `OLD` y `NEW`, ya que no son específicos de cada fila.

Ejemplos

1. Activador básico a nivel de enunciado

sql
-- This function logs an entry into audit_log whenever an INSERT, UPDATE, or DELETE operation is performed on the employees table.
CREATE FUNCTION log_total_changes() RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO audit_log(event_type, event_time)
  VALUES (TG_OP, now());
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER audit_changes
AFTER INSERT OR UPDATE OR DELETE
ON employees
FOR EACH STATEMENT
EXECUTE PROCEDURE log_total_changes();

2. Activador de operaciones de inserción

sql
-- This function logs every INSERT operation on the employees table into the insert_log table with the current timestamp.
CREATE FUNCTION log_inserts() RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO insert_log(table_name, insert_time)
  VALUES (TG_TABLE_NAME, now());
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER log_employee_inserts
AFTER INSERT
ON employees
FOR EACH STATEMENT
EXECUTE PROCEDURE log_inserts();

3. Ejecución condicional del activador

sql
-- This function conditionally calls a notification function only when a DELETE operation is performed on the orders table.
CREATE FUNCTION notify_admin() RETURNS TRIGGER AS $$
BEGIN
  IF (TG_OP = 'DELETE') THEN
    PERFORM notify_admin_function();
  END IF;
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER admin_notification
AFTER DELETE
ON orders
FOR EACH STATEMENT
EXECUTE PROCEDURE notify_admin();

En estos ejemplos, `TG_OP` se refiere al tipo de operación (`INSERT`, `UPDATE` o `DELETE`), y `TG_TABLE_NAME` se refiere al nombre de la tabla en la que está definido el activador.

Consejos y buenas prácticas

  • Limita la complejidad del activador. Mantén la lógica de activación simple para evitar efectos secundarios no deseados y mantener el rendimiento.
  • Utiliza los desencadenantes con moderación. Un uso excesivo puede provocar problemas de mantenimiento y dificultar la depuración.
  • Documenta claramente los desencadenantes. Documenta siempre la finalidad y la función de los activadores en tu base de datos.
  • Prueba a fondo. Asegúrate de que los activadores se prueban a fondo para validar su comportamiento en distintos escenarios.
  • Considera el impacto en el rendimiento. Ten en cuenta que los activadores pueden afectar al rendimiento, especialmente en entornos con muchas transacciones.
  • Considera la posibilidad de utilizar activadores a nivel de fila para la lógica específica de cada fila. Los desencadenadores a nivel de sentencia no son adecuados para operaciones específicas de fila, así que utiliza desencadenadores a nivel de fila cuando sea necesario.
  • Comprende las diferencias de activación. Los desencadenantes a nivel de sentencia se ejecutan una vez por sentencia sin acceso a filas específicas, mientras que los desencadenantes a nivel de fila se ejecutan para cada fila afectada y pueden acceder a los valores de fila `OLD` y `NEW`.