Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment activer une contrainte de clé étrangère dans SQL Server (exemples T-SQL)

Si vous avez une contrainte de clé étrangère dans SQL Server qui est actuellement désactivée, vous pouvez utiliser le code ci-dessous pour la réactiver.

Lorsque vous activez une contrainte de clé étrangère, vous avez la possibilité de spécifier si vous souhaitez ou non vérifier les données existantes dans la table. Ceci s'applique également lorsque vous activez un CHECK contrainte.

Vous trouverez ci-dessous des exemples de code d'activation d'une contrainte de clé étrangère, tout en spécifiant chacune de ces différentes options.

Exemple 1 - Activer une contrainte à l'aide de WITH CHECK

C'est la méthode recommandée (sauf si vous avez une raison particulière de ne pas l'utiliser).

Voici un exemple d'activation d'une contrainte de clé étrangère appelée FK_Albums_Artists :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; 

Ici, j'indique explicitement WITH CHECK , qui indique à SQL Server de vérifier les données existantes avant d'activer la contrainte. Si des données violent la contrainte, la contrainte ne sera pas activée et vous obtiendrez une erreur.

C'est bien, car cela renforce l'intégrité référentielle.

Lorsque vous créez une nouvelle contrainte de clé étrangère, il s'agit du paramètre par défaut. Cependant, lorsque vous activez une contrainte existante (comme nous le faisons ici), ce n'est pas le paramètre par défaut.

Exemple 2 - Activer une contrainte à l'aide de WITH NOCHECK

Dans cet exemple, la contrainte est activée sans vérifier les données existantes :

ALTER TABLE Albums 
WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;

Ici, je déclare explicitement WITH NOCHECK , qui indique à SQL Server de ne pas vérifier les données existantes. Cela signifie que la contrainte sera activée même si la table contient déjà des données qui violent la contrainte.

Il s'agit du paramètre par défaut lors de l'activation d'une contrainte (mais pas lors de sa création).

L'une des rares raisons (probablement la seule raison) pour laquelle vous l'utiliseriez est si vous souhaitez conserver des données invalides dans la base de données. Vous avez peut-être une exception ponctuelle où vous devez entrer une ligne ou plus de données non valides, mais vous avez besoin que toutes les données futures soient conformes à la contrainte.

Cependant, il y a encore des risques associés à cela. Voici ce que Microsoft a à dire à ce sujet :

Nous vous déconseillons de le faire, sauf dans de rares cas. La nouvelle contrainte est évaluée dans toutes les mises à jour de données ultérieures. Toute violation de contrainte supprimée par WITH NOCHECK lorsque la contrainte est ajoutée peut entraîner l'échec des futures mises à jour si elles mettent à jour des lignes avec des données qui ne respectent pas la contrainte.

Donc, en utilisant WITH NOCHECK pourrait potentiellement causer des problèmes plus tard.

Exemple 3 - Activer une contrainte à l'aide de l'option par défaut

Voici un exemple utilisant l'option par défaut :

ALTER TABLE Albums 
CHECK CONSTRAINT FK_Albums_Artists;

Cet exemple est l'équivalent de l'exemple précédent. Comme je n'ai pas précisé s'il fallait ou non vérifier, SQL Server suppose que je veux WITH NOCHECK .

Assurez-vous donc de spécifier explicitement WITH CHECK si vous voulez éviter les problèmes d'intégrité référentielle.

L'utilisation de WITH NOCHECK supprime la confiance

Lorsque vous activez une contrainte en utilisant (par défaut) WITH NOCHECK , une conséquence dont vous devez être conscient est que SQL Server ne fera plus confiance à cette contrainte. Il le signale comme non fiable. En fait, il est déjà signalé comme non fiable lorsque vous désactivez la contrainte.

SQL Server a un is_not_trusted drapeau qu'il met à 1 lorsque vous désactivez une contrainte de clé étrangère (ce qui signifie qu'elle n'est pas fiable), et la seule façon de la définir sur 0 (de confiance) est de spécifier WITH CHECK lors de la réactivation de la contrainte. D'autre part, en utilisant WITH NOCHECK l'active simplement sans vérifier les données existantes.

En utilisant WITH CHECK , vous vous assurez que la contrainte vérifie toutes les données existantes avant d'être activée. La seule façon de l'activer est que toutes les données existantes soient conformes à la contrainte. Une fois qu'il a vérifié toutes les données existantes, la contrainte peut alors être approuvée.

Exemple 4 - Vérifier le statut de confiance/désactivé

Vous pouvez vérifier l'état de confiance et désactivé en interrogeant le sys.foreign_keys vue système.

Comme ceci :

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Résultat :

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 1                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Cela me dit que la contrainte que j'ai activée dans l'exemple précédent ( FK_Albums_Artists ) n'est pas fiable.

C'est parce que je l'ai activé en utilisant le paramètre par défaut, qui est WITH NOCHECK .

Si je le réactive en utilisant WITH CHECK , voici ce qui se passe :

ALTER TABLE Albums 
WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;

SELECT 
  name AS 'Constraint',
  is_disabled,
  is_not_trusted
FROM sys.foreign_keys;

Résultat :

+-------------------+---------------+------------------+
| Constraint        | is_disabled   | is_not_trusted   |
|-------------------+---------------+------------------|
| FK_Albums_Artists | 0             | 0                |
| FK_Albums_Genres  | 0             | 0                |
+-------------------+---------------+------------------+

Heureusement, dans ce cas, je n'avais aucune donnée qui violait la contrainte, donc la contrainte a été activée avec succès et sa confiance a été restaurée.

S'il y avait des données qui violaient la contrainte, une erreur aurait été affichée et je serais obligé de corriger les données avant de pouvoir restaurer la confiance dans la contrainte.