Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come aggiungere una chiave primaria a una tabella esistente in SQL Server (esempi T-SQL)

Questo articolo illustra come aggiungere una chiave primaria a una tabella esistente in SQL Server usando Transact-SQL.

Una chiave primaria è una colonna che è stata configurata come identificatore univoco per una determinata tabella.

Normalmente creeresti un vincolo di chiave primaria quando crei la tabella, ma puoi anche aggiungere una chiave primaria a una tabella esistente.

Si noti che una tabella può avere solo una chiave primaria. Quindi non puoi aggiungere una chiave primaria se la tabella ne ha già una.

Inoltre, le chiavi primarie possono essere aggiunte solo a colonne definite come NOT NULL .

Esempio 1:aggiunta di un vincolo di chiave primaria

In questo esempio creo una tabella, ma dimentico di aggiungere un vincolo di chiave primaria. Quindi torno indietro e modifico la tabella per avere una chiave primaria.

Crea la tabella (ma dimentica di creare una chiave primaria ):

USE Test;

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

Risultato:

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

Spiacenti, ho dimenticato di creare la chiave primaria!

Nessun problema! Possiamo aggiungerne uno ora:

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

Risultato:

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

Ora è stata aggiunta una PRIMARY KEY vincolo per ColorId colonna.

Esempio 2:verifica del vincolo della chiave primaria

Eseguiamo il codice seguente per restituire un elenco di vincoli di chiave primaria nel database:

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

Risultato:

+------------------------------+--------+-------------------+-------------------+
| 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                 |
+------------------------------+--------+-------------------+-------------------+

I risultati saranno diversi, a seconda delle chiavi primarie nel database.

Tieni inoltre presente che questa vista di sistema restituisce più colonne di quelle che ho specificato qui, ma puoi utilizzare il * carattere jolly per restituire tutte le colonne, se lo desideri.

Esempio 3:aggiunta di una chiave primaria a una colonna che consente valori NULL

Una chiave primaria può essere aggiunta solo a colonne definite come NOT NULL . Se provi ad aggiungere una chiave primaria a una colonna che ammette valori Null, riceverai un errore.

Per dimostrarlo, creiamo un'altra tabella, ma questa volta dimenticheremo anche di specificare la colonna come NOT NULL :

USE Test;

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

Possiamo eseguire la seguente query per verificare se la colonna consente o meno valori null:

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';

Risultato:

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

Possiamo vedere che quello che abbiamo creato in precedenza (in Colors table) è nullable ed è una colonna di identità. Il secondo (nel Colors2 table) è nullable e non è una colonna di identità.

Ora proviamo ad aggiungere un vincolo di chiave primaria alla colonna nullable:

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

Risultato:

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.

Quindi, in questo caso, dovremo modificare la colonna in modo che sia NOT NULL prima di provare a definirla come chiave primaria.

Possiamo usare ALTER COLUMN all'interno di un ALTER TABLE istruzione per impostare questa colonna su NOT NULL :

ALTER TABLE Colors2
ALTER COLUMN ColorId int NOT NULL;

Controlliamo di nuovo la colonna:

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';

Risultato:

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

Quindi possiamo vedere che Colors2 ora è impostato su 0 , il che significa che non è nullable (non può contenere valori NULL).

Tieni inoltre presente che la colonna non una colonna identità. Ne parlerò più tardi.

Comunque, ora che la colonna è definita come NOT NULL possiamo andare avanti e aggiungere la chiave primaria:

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

Risultato:

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

Per verificare, controlliamo di nuovo tutti i vincoli di chiave primaria per questa tabella:

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

Risultato:

+------------------------------+--------+-------------------+-------------------+
| 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                 |
+------------------------------+--------+-------------------+-------------------+

La nostra nuova chiave primaria che abbiamo chiamato PK_Colors2_ColorId è stato aggiunto all'elenco.

Esempio 4 – Modifica di una colonna per farla diventare una colonna di identità

Le chiavi primarie vengono spesso applicate alle colonne di identità. Le colonne Identity sono definite come tali con IDENTITY parola chiave, seguita da un seme facoltativo e da un valore di incremento tra parentesi.

Quando una nuova riga viene aggiunta alla tabella, SQL Server fornisce un valore incrementale univoco per la colonna Identity.

Se prevedi di utilizzare una colonna di identità, devi averlo già fatto. Non puoi modificare una colonna esistente per farla diventare una colonna di identità.

Quando ho eseguito la query in precedenza, abbiamo potuto vedere che Colors2.ColorId la colonna non una colonna di identità (lo sappiamo perché is_identity è impostato su 0 ). Ciò significa che ho creato il PK_Colors2_ColorId chiave primaria su una colonna non di identità.

Ecco cosa succede se proviamo a modificare la tabella in modo che sia una colonna di identità:

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

Risultato:

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

Come accennato, per ovviare a questo, dobbiamo abbassare la colonna e ricominciare.

Se la colonna contiene già dati, dovrai fare del lavoro extra. Questo non rientra nell'ambito di questo articolo, ma ecco un esempio di eliminazione della colonna sopra e ricreazione come colonna di identità:

USE Test; 

DROP TABLE Colors2;

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

Risultato:

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

Si noti che questa volta non ho fornito un nome per il vincolo della chiave primaria. In questo caso, il sistema creerà un nome per esso.

Controlla velocemente la colonna:

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';

Risultato:

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

Sì, ora è una colonna di identità.

Diamo un'altra occhiata alle chiavi primarie per questa tabella:

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

Risultato:

+-------------------------------+--------+-------------------+-------------------+
| 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                 |
+-------------------------------+--------+-------------------+-------------------+

Quindi ora abbiamo una chiave primaria con nome di sistema chiamata PK__Colors2__8DA7674D8F57294D .