Uniquement DEFERRABLE
les contraintes peuvent être différées.
Permettez-moi de suggérer d'abord des alternatives supérieures :
1. INSERT
dans l'ordre
Inverser la séquence du INSERT
déclarations et rien ne doit être différé. Le plus simple et le plus rapide - si possible.
2. Commande unique
Faites-le en une commande unique . Ensuite, rien n'a encore besoin d'être reporté, car les contraintes non reportables sont vérifiées après chaque commande et les CTE sont considérés comme faisant partie d'un commandement unique :
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Pendant que vous y êtes, vous pouvez réutiliser les valeurs pour le premier INSERT
; plus sûr / plus pratique pour certains cas ou inserts multi-rangs :
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Mais j'ai besoin de contraintes différées ! (Vraiment ?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Ensuite, votre code d'origine fonctionne (un peu plus lentement, car les contraintes différées augmentent les coûts).
db<>violon ici
Connexe :
Ma réponse d'origine citait le manuel :
Mais c'était trompeur car cela ne s'applique qu'aux "actions référentielles", c'est-à-dire ce qui se passe ON UPDATE
ou ON DELETE
aux lignes de la table référencée. Le cas en question n'en fait pas partie - car @zer0hedge souligné
.