Obwohl die Jahre dieser Frage vergangen sind, möchte ich für spanischsprachige Personen klarstellen, dass die Tests in Postgres durchgeführt wurden:
Die folgende Einschränkung wurde zu einer Tabelle mit 1337 Datensätzen hinzugefügt, wobei das Kit der Primärschlüssel ist:
**Bloque 1**
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
Dies erstellt einen Standardprimärschlüssel NOT DEFERRED für die Tabelle. Wenn Sie also das nächste UPDATE versuchen, erhalten Sie folgende Fehlermeldung:
update ele_kitscompletos
set div_nkit = div_nkit + 1;
FEHLER: doppelter Schlüssel verletzt die Eindeutigkeitsbeschränkung «unique_div_nkit»
In Postgres wird durch Ausführen eines UPDATE für jede Zeile überprüft, ob die Einschränkung oder Einschränkung erfüllt ist.
Das CONSTRAINT IMMEDIATE wird nun erstellt und jede Anweisung wird separat ausgeführt:
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;
Abfrage OK, 0 Zeilen betroffen (Ausführungszeit: 0 ms; Gesamtzeit: 0 ms) Abfrage OK, 1328 Zeilen betroffen (Ausführungszeit: 858 ms; Gesamtzeit: 858 ms) FEHLER: Duplikat Viola Restricción de Unicidad «unique_div_nkit» DETAIL : Ya existe la llave (div_nkit) = (1338).
Hier ermöglicht SI das Ändern des Primärschlüssels, da er den gesamten ersten vollständigen Satz (1328 Zeilen) ausführt; Obwohl es sich in der Transaktion (BEGIN) befindet, wird der CONSTRAINT sofort nach Beendigung jedes Satzes validiert, ohne COMMIT ausgeführt zu haben. Daher wird beim Ausführen des INSERT ein Fehler generiert. Zum Schluss haben wir den CONSTRAINT DEFERRED erstellt und machen folgendes:
**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
Wenn wir jede Anweisung von ** Block 2 ** und jeden Satz einzeln ausführen, wird kein Fehler für das INSERT generiert, da es nicht validiert, sondern das endgültige COMMIT ausgeführt wird, wenn es eine Inkonsistenz feststellt.
Für vollständige Informationen in Englisch schlage ich vor, dass Sie die Links überprüfen:
Deferrable SQL-Einschränkungen im Detail
NOT DEFERRABLE versus DEFERRABLE INITIALLY SOFORT