sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo hacer que PostgreSQL inserte una fila en una tabla cuando se elimina de otra tabla?

Escribe una función disparadora. Algo como esto:

CREATE OR REPLACE FUNCTION trg_backup_row()
  RETURNS trigger AS
$BODY$
BEGIN

INSERT INTO other_tbl
SELECT (OLD).*, t.other_col                -- all columns of from old table
-- SELECT OLD.col1, OLD.col2, t.other_col  -- alternative: some cols from old tbl
FROM   third_tbl t
WHERE  t.col = OLD.col  -- link to third table with info from deleted row
AND    <unique_condition_to_avoid_multiple_rows_if_needed>;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Y un activador ON DELETE . Así:

CREATE TRIGGER delaft
  AFTER DELETE
  ON tbl
  FOR EACH ROW
  EXECUTE PROCEDURE trg_backup_row();

Elementos clave

  • Mejor que sea un gatillo AFTER DELETE y FOR EACH ROW .

  • Para devolver todas las columnas de la tabla anterior, use la sintaxis (OLD).* . Consulte el manual sobre acceso a tipos compuestos . Alternativamente OLD.* también es una sintaxis válida, porque OLD se agrega al FROM cláusula implícitamente. Para un VALUES expresión tendría que ser (OLD).* , aunque. Me gusta:

    INSERT INTO other_tbl
    VALUES((OLD).*, some_variable)
    
  • Puede incluir valores de cualquier otra tabla como lo demuestro. Solo asegúrese de obtener una sola fila o cree varias entradas.

  • A medida que el gatillo se dispara AFTER el evento, la función puede RETURN NULL .

Acerca de la visibilidad

En respuesta al comentario atento de @couling.

Mientras que las claves foráneas pueden ser declaradas como DEFERRED , esto solo aplazará la verificación de integridad, no la eliminación en sí. Filas que se eliminan en activadores ejecutados antes del actual o por ON DELETE CASCADE las claves foráneas ya no serán visibles en el momento este AFTER DELETE se llama disparador. (Obviamente, todo sucede en una transacción. Ninguno de estos detalles importa para otras transacciones, que verán todos o ninguno de los efectos. Consulte el manual para obtener más información sobre Modelo MVCC y aislamiento de transacciones .)

Por lo tanto, si desea incluir valores de filas que dependen de tal manera en su INSERT , asegúrese de llamar a este disparador antes esas filas se eliminan.

Es posible que deba hacer que este activador BEFORE DELETE .

O puede significar que debe ordenar sus disparadores en consecuencia, BEFORE los disparadores vienen antes de AFTER disparadores, obviamente. Y los activadores del mismo nivel se ejecutan en orden alfabético .

Sin embargo, siempre que sea súper preciso aquí, también podría agregar los cambios realizados en la fila (o filas dependientes) en otros BEFORE los activadores solo son visibles si se llaman antes éste.

Mi consejo para que sea un AFTER el disparador fue porque es menos propenso a complicaciones y más barato si otro disparador pudiera cancelar (revertir) el DELETE a la mitad de la operación, siempre que no se aplique nada de lo anterior.