Den här artikeln visar hur man lägger till en primärnyckel till en befintlig tabell i SQL Server med Transact-SQL.
En primärnyckel är en kolumn som har konfigurerats som den unika identifieraren för en given tabell.
Du skulle normalt skapa en primärnyckelrestriktion när du skapar tabellen, men du kan också lägga till en primärnyckel till en befintlig tabell.
Observera att en tabell bara kan ha en primärnyckel. Så du kan inte lägga till en primärnyckel om tabellen redan har en.
Även primärnycklar kan bara läggas till i kolumner som är definierade som NOT NULL
.
Exempel 1 – Lägg till en primärnyckelbegränsning
I det här exemplet skapar jag en tabell, men jag glömmer att lägga till en primärnyckelbegränsning. Så jag går sedan tillbaka och ändrar tabellen så att den har en primärnyckel.
Skapa tabellen (men glöm att skapa en primärnyckel ):
USE Test; CREATE TABLE Colors ( ColorId int IDENTITY (1,1) NOT NULL, ColorName varchar(50) );
Resultat:
Commands completed successfully. Total execution time: 00:00:00.058
Hoppsan – jag glömde att skapa primärnyckeln!
Inga problem! Vi kan lägga till en nu:
ALTER TABLE Colors ADD CONSTRAINT PK_Colors_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultat:
Commands completed successfully. Total execution time: 00:00:00.031
Detta har nu lagt till en PRIMARY KEY
begränsning för ColorId
kolumn.
Exempel 2 – Kontrollera den primära nyckelbegränsningen
Låt oss köra följande kod för att returnera en lista över primära nyckelbegränsningar i databasen:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultat:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Dina resultat kommer att vara olika beroende på de primära nycklarna i din databas.
Observera också att den här systemvyn returnerar fler kolumner än vad jag har angett här, men du kan använda *
jokertecken för att returnera alla kolumner om du vill.
Exempel 3 – Lägga till en primärnyckel till en kolumn som tillåter NULL-värden
En primärnyckel kan bara läggas till i kolumner som är definierade som NOT NULL
. Om du försöker lägga till en primärnyckel i en kolumn som är nullbar får du ett felmeddelande.
För att demonstrera detta, låt oss skapa en annan tabell, men den här gången glömmer vi också att ange kolumnen som NOT NULL
:
USE Test; CREATE TABLE Colors2 ( ColorId int, ColorName varchar(50) );
Vi kan köra följande fråga för att kontrollera om kolumnen tillåter null eller inte:
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';
Resultat:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 1 | 0 | +---------+----------+---------------+---------------+
Vi kan se att den vi skapade tidigare (i Colors
table) är nullbar och är en identitetskolumn. Den andra (i Colors2
table) är nullbar och är inte en identitetskolumn.
Låt oss nu försöka lägga till en primärnyckelrestriktion till den nullbara kolumnen:
ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultat:
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.
Så i det här fallet måste vi ändra kolumnen till att vara NOT NULL
innan vi försöker definiera den som primärnyckeln.
Vi kan använda ALTER COLUMN
i en ALTER TABLE
för att ställa in denna kolumn till NOT NULL
:
ALTER TABLE Colors2 ALTER COLUMN ColorId int NOT NULL;
Låt oss kontrollera kolumnen igen:
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';
Resultat:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 0 | +---------+----------+---------------+---------------+
Så vi kan se den där Colors2
är nu inställd på 0
, vilket betyder att det inte är nullbart (det kan inte innehålla NULL-värden).
Observera också att kolumnen inte är en identitetskolumn. Jag ska diskutera detta senare.
Hur som helst, nu när kolumnen är definierad som NOT NULL
vi kan gå vidare och lägga till primärnyckeln:
ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultat:
Commands completed successfully. Total execution time: 00:00:00.048
För att verifiera, låt oss igen kontrollera alla primärnyckelbegränsningar för denna tabell:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultat:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Vår nya primärnyckel som vi kallade PK_Colors2_ColorId
har lagts till i listan.
Exempel 4 – Ändra en kolumn till att vara en identitetskolumn
Primära nycklar används ofta på identitetskolumner. Identitetskolumner definieras som sådana med IDENTITY
nyckelord, följt av ett valfritt frö- och inkrementvärde inom parentes.
När en ny rad läggs till i tabellen tillhandahåller SQL Server ett unikt, inkrementellt värde för identitetskolumnen.
Om du planerar att använda en identitetskolumn måste du redan ha gjort det. Du kan inte ändra en befintlig kolumn till att vara en identitetskolumn.
När jag körde frågan tidigare kunde vi se att Colors2.ColorId
kolumnen är inte en identitetskolumn (vi vet detta eftersom is_identity
är inställd på 0
). Det betyder att jag skapade PK_Colors2_ColorId
primärnyckel på en icke-identitetskolumn.
Så här händer om vi försöker ändra tabellen så att den blir en identitetskolumn:
ALTER TABLE Colors2 ALTER COLUMN ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY;
Resultat:
Msg 156, Level 15, State 1, Line 3 Incorrect syntax near the keyword 'IDENTITY'.
Som nämnts, för att övervinna detta måste vi släppa kolumnen och börja om.
Om kolumnen redan innehåller data måste du göra lite extra arbete. Det ligger utanför ramen för den här artikeln, men här är ett exempel på att ta bort kolumnen ovan och återskapa den som en identitetskolumn:
USE Test; DROP TABLE Colors2; CREATE TABLE Colors2 ( ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY, ColorName varchar(50) );
Resultat:
Commands completed successfully. Total execution time: 00:00:00.049
Observera att jag inte angav ett namn för den primära nyckelbegränsningen den här gången. I det här fallet kommer systemet att skapa ett namn för det.
Kontrollera snabbt kolumnen:
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';
Resultat:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 1 | +---------+----------+---------------+---------------+
Ja, det är nu en identitetskolumn.
Låt oss ta en ny titt på de primära nycklarna för denna tabell:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultat:
+-------------------------------+--------+-------------------+-------------------+ | 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 | +-------------------------------+--------+-------------------+-------------------+
Så vi har nu en systemnamnad primärnyckel som heter PK__Colors2__8DA7674D8F57294D
.