Napište spouštěcí funkci. Něco takového:
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;
A spouštěč ON DELETE
. Takhle:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Klíčové prvky
-
Nejlepší je, aby to bylo spouštěč
AFTER DELETE
aFOR EACH ROW
. -
Chcete-li vrátit všechny sloupce ze staré tabulky, použijte syntaxi
(OLD).*
. Přečtěte si příručku o přístupu ke složeným typům . PřípadněOLD.*
je také platná syntaxe, protožeOLD
je přidán doFROM
klauzule implicitně. ProVALUES
výraz by musel být(OLD).*
, ačkoli. Jako:INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Můžete zahrnout hodnoty z jakékoli jiné tabulky, jak demonstruji. Ujistěte se, že získáte jeden řádek, nebo vytvoříte více položek.
-
Když se spouštěč spustí
AFTER
V případě události může funkceRETURN NULL
.
O viditelnosti
V reakci na bdělý komentář @couling.
Zatímco cizí klíče lze prohlásit jako DEFERRED
kód>
, pouze odloží kontrolu integrity, nikoli samotné odstranění. Řádky, které jsou odstraněny v triggerech spuštěných před tím, který je k dispozici nebo od ON DELETE CASCADE
cizí klíče již nebudou viditelné v době tohoto AFTER DELETE
se nazývá spoušť. (Všechno se samozřejmě děje v jedné transakci. Na žádné z těchto podrobností nezáleží u jiných transakcí, které zaznamenají všechny nebo žádné účinky. Další informace o Model MVCC a izolace transakcí
.)
Pokud tedy chcete do INSERT
zahrnout hodnoty z řádků závislých tímto způsobem , nezapomeňte tento spouštěč zavolat před tyto řádky budou smazány.
Možná budete muset tento spouštěč nastavit BEFORE DELETE
.
Nebo to může znamenat, že musíte spouštěče podle toho objednat BEFORE
spouštěče jsou před AFTER
spouště, samozřejmě. A spouštěče na stejné úrovni se spouštějí v abecedním pořadí
.
Nicméně pokud jsem zde velmi přesný, mohu také dodat, že změny provedené v řádku (nebo závislých řádcích) v jiných BEFORE
spouštěče jsou také viditelné pouze v případě, že jsou nazývány před tento.
Moje rada, aby to bylo AFTER
trigger byl proto, že je méně náchylný ke komplikacím a levnější, pokud by jiný spouštěč mohl zrušit (vrátit zpět) DELETE
v polovině operace – pokud neplatí nic z výše uvedeného.