DEFERRABLE
のみ 制約は延期できます。
最初に優れた代替案を提案させてください:
1。 INSERT
順番に
INSERT
のシーケンスを逆にします ステートメント 延期する必要はありません。最もシンプルで最速-可能であれば。
2。単一のコマンド
単一のコマンドで実行します 。それでも、延期できない制約は各コマンドの後にチェックされるため、延期する必要はありません。 およびCTEは単一コマンドの一部と見なされます:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
その間、最初のINSERT
の値を再利用できます。;特定のケースまたは複数行の挿入に対してより安全/より便利:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
しかし、遅延制約が必要です! (本当に?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
その後、元のコードが機能します(遅延制約によりコストがかかるため、少し遅くなります)。
db <> fiddle こちら
関連:
私の元の回答
しかし、それは「参照アクション」、つまりON UPDATE
にのみ適用されるため、誤解を招く恐れがありました。 またはON DELETE
参照されるテーブルの行に。当面のケースはそれらの1つではありません-