INSÉRER … RETOUR ..apparaît vide lorsque le déclencheur AVANT annule l'instruction
-
21-12-2019 - |
Question
J'ai un déclencheur PostgreSQL avant l'insertion lors de la création qui redirige essentiellement les insertions dans des sous-tables.Une fois que j'ai inséré l'enregistrement, je souhaite ABORTIR la demande afin d'éviter les données en double (en ne les insérant pas dans la table parent), j'utilise donc return NULL dans le déclencheur.Le problème est que j'ai besoin que le dossier soit restitué pour pouvoir obtenir la pièce d'identité.Si je renvoie NULL, j'obtiens NULL.
Le problème ci-dessus est discuté sur le lien ci-dessous :Le déclencheur PostgreSQL ne renvoie rien
L'une des réponses dit d'insérer dans la table parent (en ne renvoyant pas null mais en renvoyant nouveau) et d'utiliser le déclencheur d'insertion APRÈS pour le supprimer de la table parent.Mais je regarde 1 000 écritures par seconde et cela peut constituer un problème sérieux de performances en raison des suppressions. Existe-t-il un autre moyen de procéder ?
Pour être exact, existe-t-il un moyen de renvoyer l'identifiant d'une ligne insérée sans l'insérer dans la table parent et la supprimer ultérieurement.
La solution
J'ai écrit la réponse à laquelle vous faites référence.Comme je l'ai déjà laissé entendre là-bas :
Vous pouvez également utiliser un
RULE ... INSTEAD ..
dans ce but.
RULE
Règles peut être délicat.Je préfère utiliser des déclencheurs lorsque cela est possible. Assurez-vous de lire un peu, avant d'essayer ceci :
CREATE OR REPLACE RULE tbl_ins AS
ON INSERT TO tbl
DO INSTEAD
INSERT INTO tbl2 (col1, col2, ...) -- just do mention columns where ...
VALUES (NEW.col1, NEW.col2, ...) -- ... you want to insert column defaults
RETURNING tbl2.*
Cela renverrait les valeurs de tbl2
tout en évitant les lignes fantômes. Cependant, par documentation sur CREATE RULE
:
Dans une règle pour
INSERT
,UPDATE
, ouDELETE
sur une vue, vous pouvez ajouter unRETURNING
clause qui émet les colonnes de la vue.Cette clause sera utilisée pour calculer les sorties si la règle est déclenchée par unINSERT RETURNING
,UPDATE RETURNING
, ouDELETE RETURNING
commande respectivement.Lorsque la règle est déclenchée par une commande sansRETURNING
, les règlesRETURNING
la clause sera ignorée. L'implémentation actuelle ne permet qu'inconditionnelINSTEAD
règles à contenirRETURNING
;
C'est moi qui souligne en gras.
Puisque tu mentionnes sub-tables
, je suppose qu'il vous faudrait des conditions pour distribuer les inserts...
currval()
/ lastval()
Si vous opérez avec une gâchette FOR EACH ROW
vous pouvez facilement récupérer les valeurs appropriées à partir de séquences avec currval()
/ lastval()
.La partie la plus délicate consiste à renvoyer ces valeurs à partir d'une fonction de déclenchement.Je ne peux penser qu'à écrire sur une table temporaire.Il faut réfléchir quand créer et quand laisser tomber celui-là...
je le ferais probablement repenser toute l'approche et rediriger les données vers plusieurs INSERT
instructions aux tables cibles réelles...