Sebbene siano trascorsi gli anni di questa domanda, vorrei chiarire per i parlanti spagnoli, i test sono stati eseguiti su Postgres:
Il seguente vincolo è stato aggiunto a una tabella di 1337 record, in cui il kit è la chiave primaria:
**Bloque 1**
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
Questo crea una chiave primaria predefinita NON DEFERRED per la tabella, quindi quando proviamo il prossimo AGGIORNAMENTO otteniamo un errore:
update ele_kitscompletos
set div_nkit = div_nkit + 1;
ERRORE: la chiave duplicata viola la restrizione di unicità «unique_div_nkit»
In Postgres, l'esecuzione di un AGGIORNAMENTO per ogni ROW verifica che la RESTRIZIONE o VINCITORE sia soddisfatta.
Il VINCITORE IMMEDIATO è ora creato e ogni istruzione viene eseguita separatamente:
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY IMMEDIATE
**Bloque 2**
BEGIN;
UPDATE ele_kitscompletos set div_nkit = div_nkit + 1;
INSERT INTO public.ele_kitscompletos(div_nkit, otro_campo)
VALUES
(1338, '888150502');
COMMIT;
Query OK, 0 righe interessate (tempo di esecuzione: 0 ms; tempo totale: 0 ms) Query OK, 1328 righe interessate (tempo di esecuzione: 858 ms; tempo totale: 858 ms) ERRORE: llave duplicada viola restricción de unicidad «unique_div_nkit» DETTAGLIO : Ya existe la llave (div_nkit) = (1338).
Qui SI consente di modificare la chiave primaria poiché esegue l'intera prima frase completa (1328 righe); ma sebbene sia in transazione (INIZIO), il VINCITORE viene validato immediatamente al termine di ogni frase senza aver commesso COMMIT, quindi genera l'errore durante l'esecuzione di INSERT. Alla fine abbiamo creato il VINCITORE DEFERRED nel modo seguente:
**Bloque 3**
ALTER TABLE public.ele_edivipol
DROP CONSTRAINT unique_div_nkit RESTRICT;
ALTER TABLE ele_edivipol
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
DEFERRABLE INITIALLY DEFERRED
Se eseguiamo ogni istruzione di ** Blocco 2 **, ogni frase separatamente, non viene generato alcun errore per INSERT poiché non viene convalidato, ma il COMMIT finale viene eseguito dove trova un'incoerenza.
Per informazioni complete in inglese ti consiglio di controllare i link:
Vincoli SQL differibili in profondità
NON DEFERRABILE CONTRO DEFERRABILE INIZIALMENTE IMMEDIATO