Skriv en triggerfunktion. Något så här:
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;
Och en trigger ON DELETE
. Så här:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Nyckelelement
-
Bäst gör det till en utlösare
AFTER DELETE
ochFOR EACH ROW
. -
För att returnera alla kolumner från den gamla tabellen använd syntaxen
(OLD).*
. Se manualen om åtkomst av sammansatta typer . AlternativtOLD.*
är också giltig syntax eftersomOLD
läggs till iFROM
klausul implicit. För enVALUES
uttryck det måste vara(OLD).*
, fastän. Gilla:INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Du kan inkludera värden från vilken annan tabell som helst som jag visar. Se bara till att få en enda rad, annars skapar du flera poster.
-
När utlösaren aktiveras
AFTER
händelsen kan funktionenRETURN NULL
.
Om synlighet
Som svar på @coulings vaksamma kommentar.
Medan främmande nycklar kan deklareras som DEFERRED
kod>
, kommer detta bara att skjuta upp integritetskontrollen, inte själva borttagningen. Rader som raderas i triggers som exekveras före den aktuella eller av ON DELETE CASCADE
främmande nycklar kommer inte att vara synliga längre vid den här tiden AFTER DELETE
utlösaren anropas. (Det händer helt klart i en transaktion. Ingen av dessa detaljer spelar någon roll för andra transaktioner, som kommer att se alla eller inga effekter. Se manualen för mer om MVCC-modell och transaktionsisolering
.)
Därför, om du vill inkludera värden från rader beroende på ett sådant sätt i din INSERT
, se till att anropa den här utlösaren före dessa rader tas bort.
Du kanske måste göra denna utlösare BEFORE DELETE
.
Eller så kan det innebära att du måste beställa dina triggers därefter, BEFORE
triggers kommer före AFTER
triggers, uppenbarligen. Och triggers på samma nivå exekveras i alfabetisk ordning
.
Men så länge jag är superprecis här, kan jag också lägga till att ändringar har gjorts på raden (eller beroende rader) i andra BEFORE
utlösare är också bara synliga om de kallas före den här.
Mitt råd att göra det till en AFTER
triggern berodde på att den är mindre benägen för komplikationer och billigare om andra trigger kan avbryta (återställa) DELETE
halvvägs genom operationen - så länge inget av ovanstående gäller.