sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man lägger till en primärnyckel till en befintlig tabell i SQL Server (T-SQL-exempel)

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 .


  1. Hibernate native query - kolumn char(3).

  2. Vilket är det mest eleganta sättet att lagra tidsstämpel med nanosec i postgresql?

  3. En recension av de nya analytiska fönsterfunktionerna i MySQL 8.0

  4. 3 sätt att lista alla triggers för en given tabell i PostgreSQL