Nur DEFERRABLE
Beschränkungen können verschoben werden.
Lassen Sie mich zuerst überlegene Alternativen vorschlagen:
1. INSERT
um
Kehren Sie die Reihenfolge von INSERT
um Aussagen und nichts muss verschoben werden. Am einfachsten und schnellsten - wenn überhaupt möglich.
2. Einzelbefehl
Erledigen Sie dies mit einem einzelnen Befehl . Dann muss immer noch nichts zurückgestellt werden, da nicht-aufschiebbare Constraints nach jedem Befehl geprüft werden und CTEs werden als Teil eines einzelnen Befehls betrachtet:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Wenn Sie schon dabei sind, können Sie die Werte für das erste INSERT
wiederverwenden; sicherer / bequemer für bestimmte Fälle oder mehrreihige Einsätze:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Aber ich brauche verzögerte Beschränkungen! (Wirklich?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Dann funktioniert Ihr Originalcode (etwas langsamer, da verzögerte Einschränkungen Kosten verursachen).
db<>fiddle hier
Verwandte:
Meine ursprüngliche Antwort zitierte das Handbuch :
Aber das war irreführend, da es nur für "referenzielle Aktionen" gilt, dh was ON UPDATE
passiert oder ON DELETE
zu Zeilen in der referenzierten Tabelle. Der vorliegende Fall ist keiner von diesen - wie @zer0hedge darauf hingewiesen
.