Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como adicionar uma chave primária a uma tabela existente no SQL Server (Exemplos de T-SQL)


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 .