Solo DEFERRABLE
i vincoli possono essere differiti.
Lasciatemi suggerire prima alternative superiori:
1. INSERT
in ordine
Invertire la sequenza di INSERT
dichiarazioni e nulla deve essere differito. Il più semplice e veloce, se possibile.
2. Comando singolo
Fallo con un comando singolo . Quindi ancora nulla deve essere differito, poiché i vincoli non differibili vengono controllati dopo ogni comando e i CTE sono considerati parte di un unico comando:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Mentre ci sei, puoi riutilizzare i valori per il primo INSERT
; più sicuro/più conveniente per alcuni casi o inserti a più file:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
Ma ho bisogno di vincoli posticipati! (Davvero?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Quindi il tuo codice originale funziona (un po' più lento, poiché i vincoli posticipati aggiungono costi).
db<>violino qui
Correlati:
La mia risposta originale citava il manuale :
Ma era fuorviante in quanto si applica solo alle "azioni referenziali", ovvero cosa succede ON UPDATE
o ON DELETE
alle righe della tabella di riferimento. Il caso in questione non è uno di quelli, come @zer0hedge ha sottolineato
.