La page de documentation de MSDN sur ALTER TABLE
explique ces éléments:
ALTER TABLE
: modifier la structure de la table
(et certaines des actions / modifications possibles sont):
CHECK CONSTRAINT ..
: activer la contrainte
NOCHECK CONSTRAINT ..
: désactiver la contrainte
Il existe également des étapes supplémentaires facultatives à effectuer lors de la création / activation / désactivation d'une contrainte:
WITH CHECK
: vérifiez également la contrainte
WITH NOCHECK
: ne pas vérifier la contrainte
Dans leurs mots:
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT
{ ALL | constraint_name [ ,...n ] }
...
WITH CHECK | WITH NOCHECK
Spécifie si les données de la table sont ou non validées par rapport à une contrainte FOREIGN KEY
ou une CHECK
contrainte nouvellement ajoutée ou réactivée . S'il n'est pas spécifié, WITH CHECK
est supposé pour les nouvelles contraintes et WITH NOCHECK
est supposé pour les contraintes réactivées.
Si vous ne souhaitez pas vérifier les nouvelles CHECK
ou les FOREIGN KEY
contraintes par rapport aux données existantes, utilisez WITH NOCHECK
. Nous vous déconseillons de le faire, sauf dans de rares cas. La nouvelle contrainte sera évaluée dans toutes les mises à jour de données ultérieures. Toute violation de contrainte supprimée par WITH NOCHECK
l'ajout de la contrainte peut entraîner l'échec des mises à jour futures si elles mettent à jour les lignes avec des données non conformes à la contrainte.
L'optimiseur de requêtes ne prend pas en compte les contraintes définies WITH NOCHECK
. Ces contraintes sont ignorées jusqu'à ce qu'elles soient réactivées à l'aide de ALTER TABLE
table WITH CHECK CHECK CONSTRAINT ALL
.
...
{ CHECK | NOCHECK } CONSTRAINT
Spécifie que nom_contrainte est activé ou désactivé. Cette option ne peut être utilisée qu'avec FOREIGN KEY
et CHECK
contraintes. Lorsque NOCHECK
est spécifié, la contrainte est désactivée et les insertions ou mises à jour futures de la colonne ne sont pas validées par rapport aux conditions de contrainte. DEFAULT
, PRIMARY KEY
et les UNIQUE
contraintes ne peuvent pas être désactivées.
Test dans dbfiddle :
CREATE TABLE a (aid INT PRIMARY KEY);
ALLER
✓
INSERT INTO a (aid)
VALUES (1), (2), (3) ;
ALLER
3 lignes affectées
CREATE TABLE b
( aid INT,
bid INT PRIMARY KEY,
CONSTRAINT [My_FORIEGN_KEY]
FOREIGN KEY (aid) REFERENCES a (aid)
) ;
ALLER
✓
INSERT INTO b (aid, bid)
VALUES
(1, 11),
(1, 12),
(2, 21),
(3, 31) ;
ALLER
4 lignes affectées
INSERT INTO b (aid, bid)
VALUES
(6, 61),
(6, 62) ;
ALLER
Msg 547 Niveau 16 State 0 Line 1
L'instruction INSERT était en conflit avec la contrainte FOREIGN KEY "My_FORIEGN_KEY". Le conflit s'est produit dans la base de données "fiddle_792fce5de09f42908c3a0f91421f3522", table "dbo.a", colonne "aide".
Msg 3621 niveau 0 état 0 ligne 1
La déclaration est terminée.
SELECT * FROM b ;
ALLER
aide | offre
-: | -:
1 | 11
1 | 12
2 | 21
3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY]; --disable
ALLER
✓
INSERT INTO b (aid, bid)
VALUES
(4, 41),
(4, 42) ;
ALLER
2 lignes affectées
SELECT * FROM b ;
ALLER
aide | offre
-: | -:
1 | 11
1 | 12
2 | 21
3 | 31
4 | 41
4 | 42
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY];
-- enable constraint without checking existing data
ALLER
✓
SELECT * FROM b ;
ALLER
aide | offre
-: | -:
1 | 11
1 | 12
2 | 21
3 | 31
4 | 41
4 | 42
INSERT INTO b (aid, bid)
VALUES
(6, 61),
(6, 62) ;
ALLER
Msg 547 Niveau 16 State 0 Line 1
L'instruction INSERT était en conflit avec la contrainte FOREIGN KEY "My_FORIEGN_KEY". Le conflit s'est produit dans la base de données "fiddle_792fce5de09f42908c3a0f91421f3522", table "dbo.a", colonne "aide".
Msg 3621 niveau 0 état 0 ligne 1
La déclaration est terminée.
SELECT * FROM b ;
ALLER
aide | offre
-: | -:
1 | 11
1 | 12
2 | 21
3 | 31
4 | 41
4 | 42
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY];
-- check existing data and enable constraint
ALLER
Msg 547 Niveau 16 State 0 Line 1
L'instruction ALTER TABLE était en conflit avec la contrainte FOREIGN KEY "My_FORIEGN_KEY". Le conflit s'est produit dans la base de données "fiddle_792fce5de09f42908c3a0f91421f3522", table "dbo.a", colonne "aide".
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking
, cela signifie-t-il que la contrainte ne vérifiera pas les données existantes, seulement les nouvelles données entrantes?Pensez à lire l'article ici: https://msdn.microsoft.com/en-us/library/ms190273.aspx
Il nous dit: «L'optimiseur de requêtes ne prend pas en compte les contraintes définies AVEC NOCHECK. Ces contraintes sont ignorées jusqu'à ce qu'elles soient réactivées à l'aide de la table ALTER TABLE AVEC CHECK CHECK CONSTRAINT ALL '
Considérez également ce fil sur StackOverflow: /programming/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint
la source