sql >> Base de Datos >  >> RDS >> PostgreSQL

ESTABLECER RESTRICCIONES TODO DIFERIDO no funciona como se esperaba

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ó .