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
.