Тази статия демонстрира как да добавите първичен ключ към съществуваща таблица в SQL Server с помощта на Transact-SQL.
Първичният ключ е колона, която е конфигурирана като уникален идентификатор за дадена таблица.
Обикновено създавате ограничение за първичен ключ, когато създавате таблицата, но можете също да добавите първичен ключ към съществуваща таблица.
Имайте предвид, че една таблица може да има само един първичен ключ. Така че не можете да добавите първичен ключ, ако таблицата вече има такъв.
Също така първичните ключове могат да се добавят само към колони, които са дефинирани като NOT NULL
.
Пример 1 – Добавяне на ограничение за първичен ключ
В този пример създавам таблица, но забравям да добавя ограничение за първичен ключ. Затова се връщам и променям таблицата, за да има първичен ключ.
Създайте таблицата (но забравете да създадете първичен ключ ):
USE Test; CREATE TABLE Colors ( ColorId int IDENTITY (1,1) NOT NULL, ColorName varchar(50) );
Резултат:
Commands completed successfully. Total execution time: 00:00:00.058
Ами сега – забравих да създам първичния ключ!
Няма проблем! Можем да добавим един сега:
ALTER TABLE Colors ADD CONSTRAINT PK_Colors_ColorId PRIMARY KEY CLUSTERED (ColorId);
Резултат:
Commands completed successfully. Total execution time: 00:00:00.031
Това вече е добавило PRIMARY KEY
ограничение за ColorId
колона.
Пример 2 – Проверете ограничението на първичния ключ
Нека изпълним следния код, за да върнем списък с ограничения на първичния ключ в базата данни:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Резултат:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Резултатите ви ще бъдат различни в зависимост от първичните ключове във вашата база данни.
Също така имайте предвид, че този системен изглед връща повече колони от това, което съм посочил тук, но можете да използвате *
заместващ знак, за да върнете всички колони, ако желаете.
Пример 3 – Добавяне на първичен ключ към колона, която позволява стойности NULL
Първичен ключ може да се добавя само към колони, които са дефинирани като NOT NULL
. Ако се опитате да добавите първичен ключ към колона, която е нула, ще получите грешка.
За да демонстрираме това, нека създадем друга таблица, но този път също ще забравим да посочим колоната като NOT NULL
:
USE Test; CREATE TABLE Colors2 ( ColorId int, ColorName varchar(50) );
Можем да изпълним следната заявка, за да проверим дали колоната позволява нулеви стойности или не:
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';
Резултат:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 1 | 0 | +---------+----------+---------------+---------------+
Можем да видим, че този, който създадохме по-рано (в Colors
таблица) е нула и е колона за идентичност. Вторият (в Colors2
таблица) е нула и не е колона за идентичност.
Сега нека се опитаме да добавим ограничение за първичен ключ към колоната с нула:
ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Резултат:
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.
Така че в този случай ще трябва да променим колоната да бъде NOT NULL
преди да се опитаме да го дефинираме като първичен ключ.
Можем да използваме ALTER COLUMN
в ALTER TABLE
оператор, за да зададете тази колона на NOT NULL
:
ALTER TABLE Colors2 ALTER COLUMN ColorId int NOT 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';
Резултат:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 0 | +---------+----------+---------------+---------------+
Така че можем да видим, че Colors2
сега е настроен на 0
, което означава, че не може да бъде нула (не може да съдържа NULL стойности).
Също така имайте предвид, че колоната не колона за идентичност. Ще обсъдя това по-късно.
Както и да е, сега, когато колоната е дефинирана като NOT NULL
можем да продължим и да добавим първичния ключ:
ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Резултат:
Commands completed successfully. Total execution time: 00:00:00.048
За да проверим, нека отново проверим всички ограничения на първичния ключ за тази таблица:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Резултат:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Нашият нов първичен ключ, който нарекохме PK_Colors2_ColorId
е добавен към списъка.
Пример 4 – Промяна на колона, за да бъде колона за идентичност
Първичните ключове често се прилагат към колони за идентичност. Колоните за идентичност се дефинират като такива с IDENTITY
ключова дума, последвана от незадължителна начална стойност и стойност на увеличение в скоби.
Когато към таблицата се добави нов ред, SQL Server предоставя уникална, нарастваща стойност за колоната за идентичност.
Ако планирате да използвате колона за идентичност, трябва вече да сте го направили. Не можете да промените съществуваща колона, за да бъде колона за идентичност.
Когато изпълних заявката по-рано, можехме да видим, че Colors2.ColorId
колоната е не колона за идентичност (знаем това, защото is_identity
е настроен на 0
). Това означава, че създадох PK_Colors2_ColorId
първичен ключ в колона без идентичност.
Ето какво се случва, ако се опитаме да променим таблицата, за да бъде колона за идентичност:
ALTER TABLE Colors2 ALTER COLUMN ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY;
Резултат:
Msg 156, Level 15, State 1, Line 3 Incorrect syntax near the keyword 'IDENTITY'.
Както споменахме, за да преодолеем това, трябва да пуснем колоната и да започнем отново.
Ако колоната вече съдържа данни, ще трябва да свършите допълнителна работа. Това е извън обхвата на тази статия, но ето пример за премахване на горната колона и пресъздаването й като колона за идентичност:
USE Test; DROP TABLE Colors2; CREATE TABLE Colors2 ( ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY, ColorName varchar(50) );
Резултат:
Commands completed successfully. Total execution time: 00:00:00.049
Забележете, че този път не предоставих име за ограничението на първичния ключ. В този случай системата ще създаде име за него.
Бързо проверете колоната:
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';
Резултат:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 1 | +---------+----------+---------------+---------------+
Да, вече е колона за идентичност.
Нека да разгледаме още веднъж първичните ключове за тази таблица:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Резултат:
+-------------------------------+--------+-------------------+-------------------+ | 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 | +-------------------------------+--------+-------------------+-------------------+
Така че вече имаме първичен ключ със системно име, наречен PK__Colors2__8DA7674D8F57294D
.