Tylko DEFERRABLE
ograniczenia mogą być odroczone.
Pozwól, że najpierw zasugeruję lepsze alternatywy:
1. INSERT
w kolejności
Odwróć sekwencję INSERT
oświadczenia i nic nie trzeba odkładać. Najprostszy i najszybszy - jeśli to w ogóle możliwe.
2. Pojedyncze polecenie
Zrób to w jednym poleceniu . Wtedy nadal nic nie musi być odroczone, ponieważ nieodroczone ograniczenia są sprawdzane po każdym poleceniu i CTE są uważane za część pojedynczego polecenia:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Będąc przy tym, możesz ponownie użyć wartości dla pierwszego INSERT
; bezpieczniejsze / wygodniejsze dla niektórych przypadków lub wkładek wielorzędowych:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Ale potrzebuję odroczonych ograniczeń! (Naprawdę?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Wtedy twój oryginalny kod działa (nieco wolniej, ponieważ odroczone ograniczenia zwiększają koszty).
db<>fiddle tutaj
Powiązane:
Moja pierwotna odpowiedź zacytowała instrukcję :
Było to jednak mylące, ponieważ dotyczy tylko „działań referencyjnych”, tj. Co się dzieje ON UPDATE
lub ON DELETE
do wierszy w tabeli, do której istnieje odwołanie. Ta sprawa nie jest jedną z tych - jak wskazano @zer0hedge
.