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
yFOR EACH ROW
. -
Para devolver todas las columnas de la tabla anterior, use la sintaxis
(OLD).*
. Consulte el manual sobre acceso a tipos compuestos . AlternativamenteOLD.*
también es una sintaxis válida, porqueOLD
se agrega alFROM
cláusula implícitamente. Para unVALUES
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 puedeRETURN 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.