J'ai du T-SQL généré automatiquement, qui est probablement valide, mais je ne comprends pas vraiment.
ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];
Je sais ce qu'est une contrainte de clé étrangère, mais quelle est la CHECK CHECK
?
La page de documentation de MSDN sur ALTER TABLE
explique ceci:
ALTER TABLE
: modifie la structure de la tableCHECK CONSTRAINT ..
: activer la contrainteNOCHECK CONSTRAINT ..
: désactiver la contrainteWITH CHECK
: vérifie également la contrainteWITH NOCHECK
: ne vérifie pas la contrainteDans 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 contre un _ nouvellement ajouté ou réactivéFOREIGN KEY
ouCHECK
contrainte . Si non spécifié,WITH CHECK
est supposé pour les nouvelles contraintes, etWITH NOCHECK
est supposé pour les contraintes réactivées.Si vous ne souhaitez pas vérifier les nouveaux
CHECK
ouFOREIGN KEY
contraintes par rapport aux données existantes, utilisezWITH 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 parWITH NOCHECK
lorsque la contrainte est ajoutée peut entraîner l'échec des futures mises à jour 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 deALTER TABLE
tableWITH 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'avecFOREIGN KEY
etCHECK
contraintes. LorsqueNOCHECK
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
etUNIQUE
les contraintes ne peuvent pas être désactivées.
Testez 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 État 0 Ligne 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 L'instruction a été terminée.
SELECT * FROM b ;
ALLER
aide | enchère -: | -: 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 | enchère -: | -: 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 | enchère -: | -: 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 État 0 Ligne 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 L'instruction a été terminée.
SELECT * FROM b ;
ALLER
aide | enchère -: | -: 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 État 0 Ligne 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'.
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: https://stackoverflow.com/questions/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint