Bien que les années de cette question soient passées, je voudrais clarifier pour les hispanophones, les tests ont été effectués dans Postgres:
La contrainte suivante a été ajoutée à un tableau de 1337 enregistrements, où le kit est la clé primaire:
**Bloque 1**
ALTER TABLE ele_kitscompletos
ADD CONSTRAINT unique_div_nkit
PRIMARY KEY (div_nkit)
Cela crée une clé primaire par défaut NON DEFERRED pour la table, donc lors de la prochaine mise à jour, nous obtenons une erreur:
update ele_kitscompletos
set div_nkit = div_nkit + 1;
ERREUR: la clé en double viole la restriction d'unicité «unique_div_nkit»
Dans Postgres, l'exécution d'une MISE À JOUR pour chaque ROW vérifie que la RESTRICTION ou la CONTRAINTE est respectée.
Le CONSTRAINT IMMEDIATE est maintenant créé et chaque instruction est exécutée séparément:
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;
Requête OK, 0 lignes affectées (temps d'exécution: 0 ms; temps total: 0 ms) Requête OK, 1328 lignes affectées (temps d'exécution: 858 ms; temps total: 858 ms) ERREUR: llave duplicada alto restricción de unicidad «unique_div_nkit» DÉTAIL : Ya existe la llave (div_nkit) = (1338).
Ici, SI permet de changer la clé primaire car il exécute toute la première phrase complète (1328 lignes); mais bien qu'il soit en transaction (BEGIN), la CONTRAINTE est validée immédiatement à la fin de chaque phrase sans avoir effectué COMMIT, génère donc l'erreur lors de l'exécution de INSERT. Enfin, nous avons créé le CONSTRAINT DEFERRED, procédez comme suit:
**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
Si nous exécutons chaque instruction du ** bloc 2 **, chaque phrase séparément, aucune erreur n'est générée dans l'INSERT car il ne valide pas mais le COMMIT final est exécuté là où il trouve une incohérence.
Pour des informations complètes en anglais, je vous suggère de vérifier les liens:
Contraintes SQL reportables en profondeur
NON DÉFÉRRABLE versus DÉFÉRRABLE INITIALEMENT IMMÉDIATE