Schreiben Sie eine Triggerfunktion. Etwa so:
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;
Und einen Trigger ON DELETE
. So:
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Schlüsselelemente
-
Machen Sie es am besten zu einem Trigger
AFTER DELETE
undFOR EACH ROW
. -
Um alle Spalten aus der alten Tabelle zurückzugeben, verwenden Sie die Syntax
(OLD).*
. Siehe das Handbuch zum Zugriff auf zusammengesetzte Typen . AlternativOLD.*
ist auch syntaktisch gültig, weilOLD
wird zumFROM
hinzugefügt Klausel implizit. Für einenVALUES
Ausdruck müsste es(OLD).*
sein , obwohl. Wie:INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Sie können Werte aus jeder anderen Tabelle einschließen, wie ich es demonstriere. Stellen Sie einfach sicher, dass Sie eine einzelne Zeile erhalten, oder erstellen Sie mehrere Einträge.
-
Wenn der Trigger
AFTER
auslöst das Ereignis, kann die FunktionRETURN NULL
.
Über Sichtbarkeit
Als Antwort auf den aufmerksamen Kommentar von @couling.
Während Fremdschlüssel als DEFERRED
, verzögert dies nur die Integritätsprüfung, nicht das Löschen selbst. Zeilen, die in Triggern gelöscht werden, die vor dem vorliegenden oder ausgeführt werden durch ON DELETE CASCADE
Fremdschlüssel sind nicht mehr sichtbar zum Zeitpunkt dieses AFTER DELETE
Trigger aufgerufen wird. (Es passiert offensichtlich alles in einer Transaktion. Keines dieser Details ist für andere Transaktionen von Bedeutung, die alle oder keine der Auswirkungen sehen werden. Weitere Informationen zu MVCC-Modell und Transaktionsisolation
.)
Wenn Sie also Werte aus so abhängigen Zeilen in Ihr INSERT
aufnehmen möchten , stellen Sie sicher, dass Sie diesen Trigger vorher aufrufen diese Zeilen werden gelöscht.
Möglicherweise müssen Sie diesen Trigger BEFORE DELETE
ausführen .
Oder es kann bedeuten, dass Sie Ihre Trigger entsprechend bestellen müssen, BEFORE
Trigger kommen vor AFTER
Auslöser, offensichtlich. Und Trigger auf derselben Ebene werden in alphabetischer Reihenfolge
ausgeführt .
Solange ich hier jedoch sehr genau bin, kann ich auch hinzufügen, dass Änderungen an der Zeile (oder abhängigen Zeilen) in anderen BEFORE
vorgenommen wurden Trigger sind auch nur sichtbar, wenn diese vorher aufgerufen werden dieses hier.
Mein Rat, es zu einem AFTER
zu machen Auslöser war, weil er weniger anfällig für Komplikationen und billiger ist, wenn ein anderer Auslöser das DELETE
abbrechen (zurücksetzen) könnte nach der Hälfte des Vorgangs - solange keiner der oben genannten Punkte zutrifft.