Schrijf een triggerfunctie. Zoiets als dit:
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;
En een trigger ON DELETE
. Zoals dit:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Belangrijke elementen
-
Maak er het beste een trigger
AFTER DELETE
enFOR EACH ROW
. -
Om alle kolommen uit de oude tabel terug te geven, gebruikt u de syntaxis
(OLD).*
. Zie de handleiding over toegang tot samengestelde typen . Als alternatiefOLD.*
is ook een geldige syntaxis, omdatOLD
wordt toegevoegd aan deFROM
clausule impliciet. Voor eenVALUES
uitdrukking zou moeten zijn(OLD).*
, hoewel. Vind ik leuk:INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
U kunt waarden uit elke andere tabel opnemen, zoals ik laat zien. Zorg ervoor dat u een enkele rij krijgt, of u maakt meerdere vermeldingen.
-
Terwijl de trekker
AFTER
afgaat de gebeurtenis, de functie kanRETURN NULL
.
Over zichtbaarheid
Als reactie op de waakzame opmerking van @couling.
Hoewel buitenlandse sleutels kunnen worden gedeclareerd als DEFERRED
, zal dit alleen de integriteitscontrole uitstellen, niet de verwijdering zelf. Rijen die worden verwijderd in triggers die worden uitgevoerd vóór de vorige of door ON DELETE CASCADE
buitenlandse sleutels zullen niet meer zichtbaar zijn op het moment dat deze AFTER DELETE
trigger wordt genoemd. (Het gebeurt natuurlijk allemaal in één transactie. Geen van deze details is van belang voor andere transacties, die alle of geen van de effecten zullen zien. Raadpleeg de handleiding voor meer informatie over de MVCC-model en transactie-isolatie
.)
Daarom, als u waarden uit rijen wilt opnemen die op een dergelijke manier afhankelijk zijn in uw INSERT
, zorg ervoor dat u deze trigger voor . aanroept die rijen worden verwijderd.
Mogelijk moet u deze trigger BEFORE DELETE
. maken .
Of het kan betekenen dat u uw triggers dienovereenkomstig moet bestellen, BEFORE
triggers komen voor AFTER
triggers natuurlijk. En triggers op hetzelfde niveau worden uitgevoerd in alfabetische volgorde
.
Maar zolang ik hier super precies ben, zou ik ook kunnen toevoegen dat de wijzigingen die zijn aangebracht in de rij (of afhankelijke rijen) in andere BEFORE
triggers zijn ook alleen zichtbaar als deze voor . worden genoemd deze.
Mijn advies om er een AFTER
van te maken trigger was omdat het minder vatbaar is voor complicaties en goedkoper als een andere trigger de DELETE
zou kunnen annuleren (terugdraaien) halverwege de operatie - zolang geen van bovenstaande van toepassing is.