Pouze DEFERRABLE
omezení lze odložit.
Dovolte mi nejprve navrhnout lepší alternativy:
1. INSERT
v pořadí
Obrátit pořadí INSERT
prohlášení a nic není třeba odkládat. Nejjednodušší a nejrychlejší – pokud je to vůbec možné.
2. Jediný příkaz
Udělejte to jediným příkazem . Pak stále není třeba nic odkládat, protože neodložitelná omezení se kontrolují po každém příkazu a CTE jsou považovány za součást jediného příkazu:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Během toho můžete znovu použít hodnoty pro první INSERT
; bezpečnější / pohodlnější pro určité případy nebo víceřadé břitové destičky:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Ale potřebuji odložená omezení! (Vážně?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Pak váš původní kód funguje (trochu pomaleji, protože odložená omezení zvyšují náklady).
db<>fiddle zde
Související:
Moje původní odpověď citovala manuál :
To však bylo zavádějící, protože se vztahuje pouze na „referenční akce“, tj. co se stane ON UPDATE
nebo ON DELETE
na řádky v odkazované tabulce. Projednávaný případ není jedním z nich – jak upozornění na @zer0hedge
.