Este artigo demonstra como adicionar uma chave primária a uma tabela existente no SQL Server usando o Transact-SQL.
Uma chave primária é uma coluna que foi configurada como o identificador exclusivo de uma determinada tabela.
Você normalmente criaria uma restrição de chave primária ao criar a tabela, mas também pode adicionar uma chave primária a uma tabela existente.
Observe que uma tabela pode ter apenas uma chave primária. Portanto, você não pode adicionar uma chave primária se a tabela já tiver uma.
Além disso, as chaves primárias só podem ser adicionadas a colunas definidas como
NOT NULL
. Exemplo 1 – Adicionar uma restrição de chave primária
Neste exemplo, crio uma tabela, mas esqueço de adicionar uma restrição de chave primária. Então eu volto e altero a tabela para ter uma chave primária.
Crie a tabela (mas esqueça de criar uma chave primária ):
USE Test; CREATE TABLE Colors ( ColorId int IDENTITY (1,1) NOT NULL, ColorName varchar(50) );
Resultado:
Commands completed successfully. Total execution time: 00:00:00.058
Ops – esqueci de criar a chave primária!
Sem problemas! Podemos adicionar um agora:
ALTER TABLE Colors ADD CONSTRAINT PK_Colors_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultado:
Commands completed successfully. Total execution time: 00:00:00.031
Isso agora adicionou uma
PRIMARY KEY
restrição para o ColorId
coluna. Exemplo 2 – Verifique a restrição de chave primária
Vamos executar o seguinte código para retornar uma lista de restrições de chave primária no banco de dados:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultado:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Seus resultados serão diferentes, dependendo das chaves primárias em seu banco de dados.
Observe também que esta visão do sistema retorna mais colunas do que eu especifiquei aqui, mas você pode usar o
*
curinga para retornar todas as colunas, se desejar. Exemplo 3 – Adicionando uma chave primária a uma coluna que permite valores NULL
Uma chave primária só pode ser adicionada a colunas definidas como
NOT NULL
. Se você tentar adicionar uma chave primária a uma coluna anulável, receberá um erro. Para demonstrar isso, vamos criar outra tabela, mas desta vez, também esqueceremos de especificar a coluna como
NOT NULL
:USE Test; CREATE TABLE Colors2 ( ColorId int, ColorName varchar(50) );
Podemos executar a seguinte consulta para verificar se a coluna permite nulos ou não:
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';
Resultado:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 1 | 0 | +---------+----------+---------------+---------------+
Podemos ver que o que criamos anteriormente (no
Colors
table) é anulável e é uma coluna de identidade. O segundo (no Colors2
table) é anulável e não é uma coluna de identidade. Agora vamos tentar adicionar uma restrição de chave primária à coluna anulável:
ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultado:
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.
Portanto, neste caso, precisaremos alterar a coluna para
NOT NULL
antes de tentarmos defini-la como a chave primária. Podemos usar
ALTER COLUMN
dentro de um ALTER TABLE
instrução para definir esta coluna como NOT NULL
:ALTER TABLE Colors2 ALTER COLUMN ColorId int NOT NULL;
Vamos verificar a coluna novamente:
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';
Resultado:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 0 | +---------+----------+---------------+---------------+
Assim, podemos ver que
Colors2
agora está definido como 0
, o que significa que não é anulável (não pode conter valores NULL). Observe também que a coluna não uma coluna de identidade. Discutirei isso mais tarde.
De qualquer forma, agora que a coluna está definida como
NOT NULL
podemos ir em frente e adicionar a chave primária:ALTER TABLE Colors2 ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);
Resultado:
Commands completed successfully. Total execution time: 00:00:00.048
Para verificar, vamos verificar novamente todas as restrições de chave primária para esta tabela:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultado:
+------------------------------+--------+-------------------+-------------------+ | 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 | +------------------------------+--------+-------------------+-------------------+
Nossa nova chave primária que chamamos de
PK_Colors2_ColorId
foi adicionado à lista. Exemplo 4 – Alterando uma coluna para ser uma coluna de identidade
As chaves primárias geralmente são aplicadas a colunas de identidade. As colunas de identidade são definidas como tal com o
IDENTITY
palavra-chave, seguida por uma semente opcional e valor de incremento entre parênteses. Quando uma nova linha é adicionada à tabela, o SQL Server fornece um valor incremental exclusivo para a coluna de identidade.
Se você planeja usar uma coluna de identidade, já deve ter feito isso. Você não pode alterar uma coluna existente para ser uma coluna de identidade.
Quando executei a consulta anteriormente, pudemos ver que o
Colors2.ColorId
coluna é não uma coluna de identidade (nós sabemos disso porque is_identity
está definido como 0
). Isso significa que criei o PK_Colors2_ColorId
chave primária em uma coluna sem identidade. Aqui está o que acontece se tentarmos alterar a tabela para ser uma coluna de identidade:
ALTER TABLE Colors2 ALTER COLUMN ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY;
Resultado:
Msg 156, Level 15, State 1, Line 3 Incorrect syntax near the keyword 'IDENTITY'.
Como mencionado, para superar isso, precisamos largar a coluna e começar de novo.
Se a coluna já contiver dados, você precisará fazer algum trabalho extra. Isso está fora do escopo deste artigo, mas aqui está um exemplo de como descartar a coluna acima e recriá-la como uma coluna de identidade:
USE Test; DROP TABLE Colors2; CREATE TABLE Colors2 ( ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY, ColorName varchar(50) );
Resultado:
Commands completed successfully. Total execution time: 00:00:00.049
Observe que eu não forneci um nome para a restrição de chave primária desta vez. Nesse caso, o sistema criará um nome para ele.
Verifique rapidamente a coluna:
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';
Resultado:
+---------+----------+---------------+---------------+ | Table | Column | is_nullable | is_identity | |---------+----------+---------------+---------------| | Colors | ColorId | 0 | 1 | | Colors2 | ColorId | 0 | 1 | +---------+----------+---------------+---------------+
Sim, agora é uma coluna de identidade.
Vamos dar outra olhada nas chaves primárias para esta tabela:
SELECT name, type, unique_index_id, is_system_named FROM sys.key_constraints WHERE type = 'PK';
Resultado:
+-------------------------------+--------+-------------------+-------------------+ | 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 | +-------------------------------+--------+-------------------+-------------------+
Portanto, agora temos uma chave primária nomeada pelo sistema chamada
PK__Colors2__8DA7674D8F57294D
.