Само 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
към редове в референтната таблица. Настоящият случай не е от тези - както @zer0hedge посочи
.