Écrire une fonction déclencheur. Quelque chose comme ça :
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;
Et un déclencheur ON DELETE
. Comme ceci :
CREATE TRIGGER delaft
AFTER DELETE
ON tbl
FOR EACH ROW
EXECUTE PROCEDURE trg_backup_row();
Éléments clés
-
Le mieux est d'en faire un déclencheur
AFTER DELETE
etFOR EACH ROW
. -
Pour renvoyer toutes les colonnes de l'ancienne table, utilisez la syntaxe
(OLD).*
. Voir le manuel sur l'accès aux types composites . AlternativementOLD.*
est également une syntaxe valide, carOLD
est ajouté auFROM
clause implicitement. Pour unVALUES
expression, il devrait être(OLD).*
, pourtant. Comme :INSERT INTO other_tbl VALUES((OLD).*, some_variable)
-
Vous pouvez inclure des valeurs de n'importe quelle autre table comme je le démontre. Assurez-vous simplement d'obtenir une seule ligne, sinon vous créez plusieurs entrées.
-
Lorsque le déclencheur se déclenche
AFTER
l'événement, la fonction peutRETURN NULL
.
À propos de la visibilité
En réponse au commentaire vigilant de @couling.
Alors que les clés étrangères peuvent être déclarées comme DEFERRED
, cela ne fera que différer le contrôle d'intégrité, pas la suppression elle-même. Lignes supprimées dans les déclencheurs exécutés avant celui en cours ou par ON DELETE CASCADE
les clés étrangères ne seront plus visibles au moment où cet AFTER DELETE
le déclencheur est appelé. (Tout se passe évidemment en une seule transaction. Aucun de ces détails n'a d'importance pour les autres transactions, qui verront tout ou aucun des effets. Reportez-vous au manuel pour en savoir plus sur le Modèle MVCC et isolation des transactions
.)
Par conséquent, si vous souhaitez inclure des valeurs de lignes dépendant de cette manière dans votre INSERT
, assurez-vous d'appeler ce déclencheur avant ces lignes sont supprimées.
Vous devrez peut-être faire ce déclencheur BEFORE DELETE
.
Ou cela peut signifier que vous devez ordonner vos déclencheurs en conséquence, BEFORE
les déclencheurs viennent avant AFTER
déclencheurs, évidemment. Et les déclencheurs au même niveau sont exécutés dans ordre alphabétique
.
Cependant, tant que je suis super précis ici, je pourrais également ajouter que les modifications apportées à la ligne (ou aux lignes dépendantes) dans d'autres BEFORE
les déclencheurs ne sont également visibles que s'ils sont appelés avant celui-ci.
Mon conseil pour en faire un AFTER
le déclencheur était parce qu'il est moins sujet aux complications et moins cher si un autre déclencheur pouvait annuler (annuler) le DELETE
à mi-chemin de l'opération - tant qu'aucune des conditions ci-dessus ne s'applique.