Endast DEFERRABLE
begränsningar kan skjutas upp.
Låt mig först föreslå överlägsna alternativ:
1. INSERT
i ordning
Vänd om sekvensen för INSERT
uttalanden och ingenting behöver skjutas upp. Enklast och snabbast - om det är möjligt.
2. Enstaka kommando
Gör det med ett enda kommando . Då behöver fortfarande ingenting skjutas upp, eftersom icke-uppskjutbara begränsningar kontrolleras efter varje kommando och CTE:er anses vara en del av ett enda kommando:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Medan du håller på kan du återanvända värdena för den första INSERT
; säkrare/bekvämare för vissa fodral eller skär med flera rader:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Men jag behöver uppskjutna begränsningar! (Verkligen?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Då fungerar din ursprungliga kod (lite långsammare, eftersom uppskjutna begränsningar ökar kostnaden).
db<>fiol här
Relaterat:
Mitt ursprungliga svar citerade manualen :
Men det var missvisande eftersom det bara gäller "referensåtgärder", dvs vad som händer ON UPDATE
eller ON DELETE
till rader i den refererade tabellen. Det aktuella fallet är inte ett av dessa - eftersom @zer0hedge påpekade
.