sql >> Databáze >  >> RDS >> PostgreSQL

SET CONSTRAINTS ALL DEFERRED nefunguje podle očekávání

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 .



  1. Dotaz MySQL pro aktualizaci záznamů se zvýšeným datem

  2. Udržování integrity podtřídy v relační databázi

  3. SQL Vytváření závislostí tabulek

  4. Názvy tabulek Postgresql a unicode:Proč nemohu vybrat název tabulky z informačního schématu, když obsahuje znaky Unicode?