PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

SET CONSTRAINTS ALL DEFERRED não está funcionando como esperado


Somente DEFERRABLE restrições podem ser adiadas.

Deixe-me sugerir alternativas superiores primeiro:

1. INSERT em ordem


Inverta a sequência do INSERT declarações e nada precisa ser adiado. Mais simples e rápido - se possível.

2. Comando único


Faça isso em um comando único . Então ainda nada precisa ser adiado, pois as restrições não adiáveis ​​são verificadas após cada comando e CTEs são considerados parte do comando único:
WITH ins1 AS (
   INSERT INTO b(j) VALUES(2)
   )
INSERT INTO a(i) VALUES(2);

Enquanto estiver nisso, você pode reutilizar os valores para o primeiro INSERT; mais seguro / mais conveniente para certos casos ou pastilhas de várias linhas:
WITH ins1 AS (
   INSERT INTO b(j) VALUES(3)
   RETURNING j
   )
INSERT INTO a(i)
SELECT j FROM ins1;

Mas eu preciso de restrições adiadas! (Sério?)

ALTER TABLE b ADD CONSTRAINT fkey_ij FOREIGN KEY (j)
   REFERENCES a (i) MATCH SIMPLE
   ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE;  -- !!!

Em seguida, seu código original funciona (um pouco mais lento, pois as restrições adiadas aumentam o custo).

db<>fiddle aqui

Relacionado:

Minha resposta original citava o manual :

Mas isso foi enganoso, pois se aplica apenas a "ações referenciais", ou seja, o que acontece ON UPDATE ou ON DELETE para linhas na tabela referenciada. O caso em questão não é um desses - como @zer0hedge apontado .