Scrivi una funzione di attivazione. Qualcosa del genere:
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;
E un trigger ON DELETE
. In questo modo:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Elementi chiave
-
È meglio che sia un trigger
AFTER DELETE
eFOR EACH ROW
. -
Per restituire tutte le colonne della vecchia tabella, usa la sintassi
(OLD).*
. Consulta il manuale sull'accesso ai tipi compositi . In alternativaOLD.*
è anche una sintassi valida, perchéOLD
viene aggiunto aFROM
clausola implicitamente. Per unVALUES
espressione dovrebbe essere(OLD).*
, anche se. Come:INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Puoi includere valori da qualsiasi altra tabella come dimostro. Assicurati solo di ottenere una singola riga o di creare più voci.
-
Quando il trigger si attiva
AFTER
l'evento, la funzione puòRETURN NULL
.
Informazioni sulla visibilità
In risposta al commento attento di @couling.
Mentre le chiavi esterne possono essere dichiarate come DEFERRED
, questo differirà solo il controllo di integrità, non l'eliminazione stessa. Righe che vengono eliminate nei trigger eseguiti prima di quello a portata di mano o da ON DELETE CASCADE
le chiavi esterne non saranno più visibili al momento questo AFTER DELETE
viene chiamato il trigger. (Succede tutto in una transazione ovviamente. Nessuno di questi dettagli è importante per altre transazioni, che vedranno tutti o nessuno degli effetti. Fare riferimento al manuale per ulteriori informazioni su Modello MVCC e isolamento delle transazioni
.)
Pertanto, se vuoi includere i valori delle righe che dipendono in questo modo nel tuo INSERT
, assicurati di chiamare questo attivatore prima quelle righe vengono eliminate.
Potrebbe essere necessario eseguire questo trigger BEFORE DELETE
.
Oppure può significare che devi ordinare i tuoi trigger di conseguenza, BEFORE
i trigger vengono prima di AFTER
trigger, ovviamente. E i trigger allo stesso livello vengono eseguiti in ordine alfabetico
.
Tuttavia, fintanto che sono super preciso qui, potrei anche aggiungere le modifiche apportate alla riga (o righe dipendenti) in altri BEFORE
i trigger sono visibili solo se vengono chiamati prima questo.
Il mio consiglio di renderlo un AFTER
trigger è dovuto al fatto che è meno soggetto a complicazioni ed è più economico se un altro trigger potrebbe annullare (ripristinare) il DELETE
a metà dell'operazione, purché non si applichi nessuna delle precedenti.