sql >> Database >  >> RDS >> Sqlserver

Een primaire sleutel toevoegen aan een bestaande tabel in SQL Server (T-SQL-voorbeelden)

Dit artikel laat zien hoe u een primaire sleutel toevoegt aan een bestaande tabel in SQL Server met behulp van Transact-SQL.

Een primaire sleutel is een kolom die is geconfigureerd als de unieke id voor een bepaalde tabel.

Normaal gesproken maakt u een primaire-sleutelbeperking wanneer u de tabel maakt, maar u kunt ook een primaire sleutel aan een bestaande tabel toevoegen.

Merk op dat een tabel slechts één primaire sleutel kan hebben. U kunt dus geen primaire sleutel toevoegen als de tabel er al een heeft.

Ook kunnen primaire sleutels alleen worden toegevoegd aan kolommen die zijn gedefinieerd als NOT NULL .

Voorbeeld 1 – Een primaire sleutelbeperking toevoegen

In dit voorbeeld maak ik een tabel, maar ik vergeet een primaire sleutelbeperking toe te voegen. Dus ik ga dan terug en verander de tabel om een ​​primaire sleutel te hebben.

Maak de tabel aan (maar vergeet een primaire sleutel te maken ):

USE Test;

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

Resultaat:

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

Oeps – ik ben vergeten de primaire sleutel te maken!

Geen probleem! We kunnen er nu een toevoegen:

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

Resultaat:

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

Dit heeft nu een PRIMARY KEY . toegevoegd beperking voor de ColorId kolom.

Voorbeeld 2 – Controleer de primaire sleutelbeperking

Laten we de volgende code uitvoeren om een ​​lijst met primaire sleutelbeperkingen in de database te retourneren:

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

Resultaat:

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

Uw resultaten zullen verschillen, afhankelijk van de primaire sleutels in uw database.

Houd er ook rekening mee dat deze systeemweergave meer kolommen retourneert dan ik hier heb opgegeven, maar u kunt de * gebruiken wildcard om desgewenst alle kolommen terug te geven.

Voorbeeld 3 – Een primaire sleutel toevoegen aan een kolom die NULL-waarden toelaat

Een primaire sleutel kan alleen worden toegevoegd aan kolommen die zijn gedefinieerd als NOT NULL . Als je een primaire sleutel probeert toe te voegen aan een kolom die nullable is, krijg je een foutmelding.

Laten we om dit te demonstreren een andere tabel maken, maar deze keer vergeten we ook de kolom op te geven als NOT NULL :

USE Test;

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

We kunnen de volgende query uitvoeren om te controleren of de kolom nulls toestaat of niet:

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

Resultaat:

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

We kunnen zien dat degene die we eerder hebben gemaakt (in de Colors tabel) is nullable en is een identiteitskolom. De tweede (in de Colors2 tabel) is nullable en is geen identiteitskolom.

Laten we nu proberen een primaire sleutelbeperking toe te voegen aan de nullable-kolom:

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

Resultaat:

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.

Dus in dit geval moeten we de kolom wijzigen in NOT NULL voordat we het proberen te definiëren als de primaire sleutel.

We kunnen ALTER COLUMN . gebruiken binnen een ALTER TABLE statement om deze kolom in te stellen op NOT NULL :

ALTER TABLE Colors2
ALTER COLUMN ColorId int NOT NULL;

Laten we de kolom nogmaals controleren:

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

Resultaat:

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

Dus we kunnen zien dat Colors2 is nu ingesteld op 0 , wat betekent dat het niet nullable is (het kan geen NULL-waarden bevatten).

Houd er ook rekening mee dat de kolom niet . is een identiteitskolom. Ik zal dit later bespreken.

Hoe dan ook, nu de kolom is gedefinieerd als NOT NULL we kunnen doorgaan en de primaire sleutel toevoegen:

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

Resultaat:

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

Laten we ter verificatie nogmaals alle primaire-sleutelbeperkingen voor deze tabel controleren:

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

Resultaat:

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

Onze nieuwe primaire sleutel die we PK_Colors2_ColorId . hebben genoemd is toegevoegd aan de lijst.

Voorbeeld 4 – Een kolom wijzigen in een identiteitskolom

Primaire sleutels worden vaak toegepast op identiteitskolommen. Identiteitskolommen worden als zodanig gedefinieerd met de IDENTITY trefwoord, gevolgd door een optionele seed- en incrementwaarde tussen haakjes.

Wanneer een nieuwe rij aan de tabel wordt toegevoegd, biedt SQL Server een unieke, incrementele waarde voor de identiteitskolom.

Als u van plan bent een identiteitskolom te gebruiken, moet u dat al gedaan hebben. U kunt een bestaande kolom niet wijzigen in een identiteitskolom.

Toen ik de query eerder uitvoerde, konden we zien dat de Colors2.ColorId kolom is niet een identiteitskolom (we weten dit omdat is_identity is ingesteld op 0 ). Dit betekent dat ik de PK_Colors2_ColorId . heb gemaakt primaire sleutel op een niet-identiteitskolom.

Dit is wat er gebeurt als we proberen de tabel te veranderen in een identiteitskolom:

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

Resultaat:

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

Zoals gezegd, om dit te verhelpen, moeten we de kolom laten vallen en opnieuw beginnen.

Als de kolom al gegevens bevat, moet u wat extra werk doen. Dat valt buiten het bestek van dit artikel, maar hier is een voorbeeld van het verwijderen van de bovenstaande kolom en het opnieuw maken van een identiteitskolom:

USE Test; 

DROP TABLE Colors2;

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

Resultaat:

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

Merk op dat ik deze keer geen naam heb gegeven voor de primaire sleutelbeperking. In dit geval zal het systeem er een naam voor maken.

Controleer snel de kolom:

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

Resultaat:

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

Ja, het is nu een identiteitskolom.

Laten we nog eens kijken naar de primaire sleutels voor deze tabel:

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

Resultaat:

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

We hebben nu dus een primaire sleutel met de naam PK__Colors2__8DA7674D8F57294D .


  1. Rails:Geen verbindingspool voor ActiveRecord::Base

  2. LN() Functie in Oracle

  3. MySQL:#126 - Onjuist sleutelbestand voor tabel

  4. Dynamisch kolommen genereren voor kruistabel in PostgreSQL