Solo DEFERRABLE
las restricciones se pueden aplazar.
Permítanme sugerir alternativas superiores primero:
1. INSERT
en orden
Invierta la secuencia de INSERT
declaraciones y nada necesita ser aplazado. Lo más simple y rápido, si es posible.
2. Comando único
Hazlo en un comando único . Entonces todavía no es necesario aplazar nada, ya que las restricciones no aplazables se comprueban después de cada comando y los CTE se consideran parte del mando único:
WITH ins1 AS (
INSERT INTO b(j) VALUES(2)
)
INSERT INTO a(i) VALUES(2);
Mientras lo hace, puede reutilizar los valores para el primer INSERT
; más seguro / más conveniente para ciertos casos o insertos de varias filas:
WITH ins1 AS (
INSERT INTO b(j) VALUES(3)
RETURNING j
)
INSERT INTO a(i)
SELECT j FROM ins1;
¡Pero necesito restricciones diferidas! (¿En serio?)
ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
REFERENCES a (i) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE; -- !!!
Luego, su código original funciona (un poco más lento, ya que las restricciones diferidas agregan costos).
db<>fiddle aquí
Relacionado:
Mi respuesta original cita el manual :
Pero eso fue engañoso ya que solo se aplica a las "acciones referenciales", es decir, lo que sucede ON UPDATE
o ON DELETE
a las filas de la tabla a la que se hace referencia. El caso que nos ocupa no es uno de esos, como @zer0hedge señaló
.