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 DELETEeFOR 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éOLDviene aggiunto aFROMclausola implicitamente. Per unVALUESespressione 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
AFTERl'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.