Dans cet article, je montre comment créer une clé étrangère dans SQL Server à l'aide de Transact-SQL. Je montre comment créer une clé étrangère au moment de la création de la table (par opposition à la mise à jour d'une table existante).
Une clé étrangère est une colonne qui fait référence à la colonne de clé primaire d'une autre table. Cela crée une relation entre les tables.
Exemple 1 – Préparation
Dans cet exemple, je vais créer une base de données de test avec une table. Cette table contiendra la clé primaire à laquelle notre clé étrangère fera référence.
Créez la base de données :
CREATE DATABASE FK_Test;
Créez maintenant la table de clé primaire :
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
Exemple 2 - Créer la clé étrangère
Maintenant que nous avons une table avec une clé primaire, créons une autre table avec une clé étrangère qui fait référence à cette clé primaire.
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
C'est le moyen le plus simple de créer une clé étrangère. Tout ce que nous faisons est d'ajouter les REFERENCES
clause (avec la table et la colonne de clé primaire) à la colonne qui aura la contrainte de clé étrangère.
Pour être clair, la partie qui définit la clé étrangère est la suivante :
REFERENCES Country(CountryId)
Ceci est inclus dans la définition de la colonne et indique simplement que cette colonne référencera le CountryId
colonne dans le Country
tableau.
Dans ce cas, la clé étrangère et la clé primaire qu'elle référence partagent le même nom (CountryId
). Cependant, ce n'est pas une exigence - votre colonne de clé étrangère peut avoir un nom complètement différent de la colonne à laquelle elle fait référence (bien que toutes les colonnes participant à une relation de clé étrangère doivent être définies avec la même longueur et la même échelle).
Dans cet exemple, SQL Server génère automatiquement le nom de la clé étrangère. C'est parce que je n'ai pas donné de nom. Lisez la suite pour voir comment vous pouvez créer un nom pour votre clé étrangère.
Mais d'abord, vérifions la contrainte de clé étrangère que nous venons de créer.
Exemple 3 - Vérifier la contrainte de clé étrangère
Il existe de nombreuses façons de renvoyer une clé étrangère à l'aide de T-SQL, et en voici une :
EXEC sp_fkeys @fktable_name = City;
Résultat (en utilisant la sortie verticale) :
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 1 DELETE_RULE | 1 FK_NAME | FK__City__CountryId__38996AB5 PK_NAME | PK__Country__10D1609FC8BFA7F2 DEFERRABILITY | 7
Les sp_fkeys
La procédure stockée du système renvoie des informations sur notre clé étrangère, sa clé primaire associée et d'autres détails pertinents. Vous transmettez simplement le nom de la table de clé étrangère ou de la table de clé primaire, et elle renverra les informations pertinentes.
Dans cet exemple, je passe le nom de la table de clé étrangère – City
. Dans les résultats, nous pouvons regarder le
FK_NAME
colonne pour voir que cette table a une contrainte de clé étrangère appelée
FK__City__CountryId__38996AB5
. C'est celui que nous venons de créer.
Maintenant que nous avons créé la clé étrangère, chaque fois que nous tentons d'insérer ou de mettre à jour une valeur dans City.CountryId
colonne, la contrainte de clé étrangère ne l'autorisera que si la même valeur existe déjà dans le Country.CountryId
colonne. Cela garantit que l'intégrité référentielle est maintenue dans la base de données.
Exemple 4 - Plus d'options
Il est possible d'ajouter plus d'options à votre définition de clé étrangère.
Par exemple, vous pouvez fournir un nom pour la clé étrangère. Vous pouvez également spécifier ce qui doit arriver aux valeurs de cette colonne si la valeur correspondante dans la clé primaire est mise à jour ou supprimée.
Ici, je crée à nouveau les deux tables, mais cette fois je spécifie explicitement ces options (je fais de même pour les clés primaires) :
CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_Country_CountryId PRIMARY KEY CLUSTERED (CountryId), CountryName nvarchar(60) ); CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_City_CityId PRIMARY KEY CLUSTERED (CityId), CountryId int NOT NULL, CONSTRAINT FK_City_Country FOREIGN KEY (CountryID) REFERENCES Country (CountryID) ON DELETE CASCADE ON UPDATE CASCADE, CityName nvarchar(60) );
Dans ce cas, la définition de la clé étrangère commence par CONSTRAINT
, suivi du nom de la clé étrangère, suivi de FOREIGN KEY
, suivi de la colonne à laquelle la contrainte de clé étrangère sera appliquée (insérée entre parenthèses).
On voit alors les mêmes REFERENCES
clause que nous avons vue dans l'exemple précédent.
Le ON DELETE CASCADE
et ON UPDATE CASCADE
les clauses sont utilisées pour s'assurer que les modifications apportées à Country
table sont automatiquement propagées à la City
table. Par exemple, si une ligne est supprimée de la table parent (clé primaire), toutes les lignes correspondantes sont supprimées de la table de référence (clé étrangère).
La valeur par défaut pour ON DELETE
et ON UPDATE
est NO ACTION
. Dans ce cas, le moteur de base de données génère une erreur et l'action de mise à jour ou de suppression sur la ligne de la table parent est annulée.
Vous pouvez également utiliser SET NULL
pour définir la colonne de clé étrangère sur NULL
(nécessite que la colonne de clé étrangère accepte les valeurs NULL) ou SET DEFAULT
pour la définir sur sa valeur par défaut (nécessite que la colonne de clé étrangère ait une définition par défaut. Si une colonne est nullable et qu'aucune valeur par défaut explicite n'est définie, NULL
devient la valeur par défaut implicite de la colonne).
Dans cet exemple j'en ai aussi profité pour nommer les clés primaires. Vous pouvez voir que la syntaxe de la clé primaire est similaire à la syntaxe de la clé étrangère, mais sans les REFERENCES
clause (et avec un CLUSTERED
ajouté argument, qui est la valeur par défaut pour les clés primaires).
Vérifiez maintenant la clé étrangère :
EXEC sp_fkeys @fktable_name = City;
Résultat :
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 0 DELETE_RULE | 0 FK_NAME | FK_City_Country PK_NAME | PK_Country_CountryId DEFERRABILITY | 7
Nous pouvons voir que le nom de la clé étrangère est maintenant FK_City_Country et la contrainte de clé primaire de la colonne à laquelle elle fait référence est appelée PK_Country_CountryId .
Exemple 5 - Clé étrangère sur plusieurs colonnes
Vous pouvez également créer une clé étrangère sur plusieurs colonnes qui fait référence à une clé primaire multicolonne. Les clés primaires multicolonnes sont également appelées clés primaires composites. Pour créer une clé étrangère composite, séparez simplement les colonnes par une virgule lors de la définition de la clé.
Comme ceci :
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
Voir Comment créer une clé étrangère composite dans SQL Server pour un exemple plus détaillé.
La clé primaire est-elle vraiment nécessaire ?
Une clé primaire n'est pas absolument nécessaire pour les clés étrangères, car vous pouvez utiliser une contrainte unique ou un index unique. Plus précisément, la documentation Microsoft indique ceci :
FOREIGN KEY
les contraintes ne peuvent référencer que des colonnes dansPRIMARY KEY
ouUNIQUE
contraintes dans la table référencée ou dans unUNIQUE INDEX
sur la table référencée.
Ainsi, bien qu'il soit généralement recommandé d'avoir des clés primaires sur toutes les tables, vos clés étrangères ne sont pas obligées de les référencer.