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

Comment ajouter une clé primaire à une table existante dans SQL Server (exemples T-SQL)

Cet article montre comment ajouter une clé primaire à une table existante dans SQL Server à l'aide de Transact-SQL.

Une clé primaire est une colonne qui a été configurée comme identifiant unique pour une table donnée.

Vous devez normalement créer une contrainte de clé primaire lorsque vous créez la table, mais vous pouvez également ajouter une clé primaire à une table existante.

Notez qu'une table ne peut avoir qu'une seule clé primaire. Vous ne pouvez donc pas ajouter de clé primaire si la table en a déjà une.

De plus, les clés primaires ne peuvent être ajoutées qu'aux colonnes définies comme NOT NULL .

Exemple 1 – Ajouter une contrainte de clé primaire

Dans cet exemple, je crée une table, mais j'oublie d'ajouter une contrainte de clé primaire. Je reviens donc en arrière et modifie la table pour avoir une clé primaire.

Créez la table (mais oubliez de créer une clé primaire ):

USE Test;

CREATE TABLE Colors
(
    ColorId int IDENTITY (1,1) NOT NULL,
    ColorName varchar(50)
);

Résultat :

Commands completed successfully.
Total execution time: 00:00:00.058

Oups, j'ai oublié de créer la clé primaire !

Aucun problème! Nous pouvons en ajouter un maintenant :

ALTER TABLE Colors
ADD CONSTRAINT PK_Colors_ColorId PRIMARY KEY CLUSTERED (ColorId);

Résultat :

Commands completed successfully.
Total execution time: 00:00:00.031

Ceci a maintenant ajouté une PRIMARY KEY contrainte pour le ColorId colonne.

Exemple 2 - Vérifier la contrainte de clé primaire

Exécutons le code suivant pour renvoyer une liste de contraintes de clé primaire dans la base de données :

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Résultat :

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9 | PK     | 1                 | 1                 |
| PK_Colors_ColorId            | PK     | 1                 | 0                 |
+------------------------------+--------+-------------------+-------------------+

Vos résultats seront différents selon les clés primaires de votre base de données.

Notez également que cette vue système renvoie plus de colonnes que ce que j'ai spécifié ici, mais vous pouvez utiliser le * caractère générique pour renvoyer toutes les colonnes si vous le souhaitez.

Exemple 3 - Ajout d'une clé primaire à une colonne qui autorise les valeurs NULL

Une clé primaire ne peut être ajoutée qu'aux colonnes définies comme NOT NULL . Si vous essayez d'ajouter une clé primaire à une colonne acceptant les valeurs NULL, vous obtiendrez une erreur.

Pour illustrer cela, créons une autre table, mais cette fois, nous oublierons également de spécifier la colonne comme NOT NULL :

USE Test;

CREATE TABLE Colors2
(
    ColorId int,
    ColorName varchar(50)
);

Nous pouvons exécuter la requête suivante pour vérifier si la colonne autorise ou non les valeurs nulles :

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Résultat :

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 1             | 0             |
+---------+----------+---------------+---------------+

Nous pouvons voir que celui que nous avons créé précédemment (dans le champ Colors table) est nullable et est une colonne d'identité. Le second (dans le Colors2 table) est nullable et n'est pas une colonne d'identité.

Essayons maintenant d'ajouter une contrainte de clé primaire à la colonne nullable :

ALTER TABLE Colors2
ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);

Résultat :

Msg 8111, Level 16, State 1, Line 1
Cannot define PRIMARY KEY constraint on nullable column in table 'Colors2'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint or index. See previous errors.

Donc, dans ce cas, nous devrons modifier la colonne pour qu'elle soit NOT NULL avant d'essayer de la définir comme clé primaire.

Nous pouvons utiliser ALTER COLUMN dans un ALTER TABLE instruction pour définir cette colonne sur NOT NULL :

ALTER TABLE Colors2
ALTER COLUMN ColorId int NOT NULL;

Vérifions à nouveau la colonne :

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Résultat :

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 0             | 0             |
+---------+----------+---------------+---------------+

Nous pouvons donc voir que Colors2 est maintenant défini sur 0 , ce qui signifie qu'il n'est pas nullable (il ne peut pas contenir de valeurs NULL).

Notez également que la colonne n'est pas une colonne d'identité. J'en parlerai plus tard.

Quoi qu'il en soit, maintenant que la colonne est définie comme NOT NULL nous pouvons continuer et ajouter la clé primaire :

ALTER TABLE Colors2
ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);

Résultat :

Commands completed successfully.
Total execution time: 00:00:00.048

Pour vérifier, vérifions à nouveau toutes les contraintes de clé primaire pour cette table :

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Résultat :

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9 | PK     | 1                 | 1                 |
| PK_Colors_ColorId            | PK     | 1                 | 0                 |
| PK_Colors2_ColorId           | PK     | 1                 | 0                 |
+------------------------------+--------+-------------------+-------------------+

Notre nouvelle clé primaire que nous avons appelée PK_Colors2_ColorId a été ajouté à la liste.

Exemple 4 - Modification d'une colonne pour en faire une colonne d'identité

Les clés primaires sont souvent appliquées aux colonnes d'identité. Les colonnes d'identité sont définies comme telles avec le IDENTITY mot-clé, suivi d'une valeur de départ et d'incrément facultative entre parenthèses.

Lorsqu'une nouvelle ligne est ajoutée à la table, SQL Server fournit une valeur incrémentielle unique pour la colonne d'identité.

Si vous prévoyez d'utiliser une colonne d'identité, vous devez l'avoir déjà fait. Vous ne pouvez pas modifier une colonne existante pour en faire une colonne d'identité.

Lorsque j'ai exécuté la requête plus tôt, nous avons pu voir que le Colors2.ColorId la colonne n'est pas une colonne d'identité (nous le savons car is_identity est défini sur 0 ). Cela signifie que j'ai créé le PK_Colors2_ColorId clé primaire sur une colonne sans identité.

Voici ce qui se passe si nous essayons de modifier la table pour en faire une colonne d'identité :

ALTER TABLE Colors2
ALTER COLUMN 
  ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY;

Résultat :

Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'IDENTITY'.

Comme mentionné, pour surmonter cela, nous devons supprimer la colonne et recommencer.

Si la colonne contient déjà des données, vous devrez effectuer un travail supplémentaire. Cela sort du cadre de cet article, mais voici un exemple de suppression de la colonne ci-dessus et de recréation en tant que colonne d'identité :

USE Test; 

DROP TABLE Colors2;

CREATE TABLE Colors2
(
    ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    ColorName varchar(50)
);

Résultat :

Commands completed successfully.
Total execution time: 00:00:00.049

Notez que je n'ai pas fourni de nom pour la contrainte de clé primaire cette fois. Dans ce cas, le système lui créera un nom.

Vérifiez rapidement la colonne :

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Résultat :

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 0             | 1             |
+---------+----------+---------------+---------------+

Oui, c'est maintenant une colonne d'identité.

Reprenons les clés primaires de cette table :

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Résultat :

+-------------------------------+--------+-------------------+-------------------+
| name                          | type   | unique_index_id   | is_system_named   |
|-------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF  | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9  | PK     | 1                 | 1                 |
| PK_Colors_ColorId             | PK     | 1                 | 0                 |
| PK__Colors2__8DA7674D8F57294D | PK     | 1                 | 1                 |
+-------------------------------+--------+-------------------+-------------------+

Nous avons donc maintenant une clé primaire nommée par le système appelée PK__Colors2__8DA7674D8F57294D .