Neste artigo demonstro como criar uma chave estrangeira no SQL Server usando Transact-SQL. Demonstro como criar uma chave estrangeira no momento da criação da tabela (em oposição à atualização de uma tabela existente).
Uma chave estrangeira é uma coluna que faz referência à coluna de chave primária de outra tabela. Isso cria um relacionamento entre as tabelas.
Exemplo 1 – Preparação
Neste exemplo, criarei um banco de dados de teste com uma tabela. Esta tabela conterá a chave primária que nossa chave estrangeira fará referência.
Crie o banco de dados:
CREATE DATABASE FK_Test;
Agora crie a tabela de chave primária:
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
Exemplo 2 – Criar a chave estrangeira
Agora que temos uma tabela com uma chave primária, vamos criar outra tabela com uma chave estrangeira que faça referência a essa chave primária.
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
Esta é a maneira mais simples de criar uma chave estrangeira. Tudo o que fazemos é adicionar as
REFERENCES
cláusula (juntamente com a tabela e coluna de chave primária) para a coluna que terá a restrição de chave estrangeira. Para ser claro, a parte que define a chave estrangeira é esta:
REFERENCES Country(CountryId)
Isso está incluído na definição da coluna e simplesmente indica que esta coluna fará referência ao
CountryId
coluna no Country
tabela. Nesse caso, tanto a chave estrangeira quanto a chave primária à qual ela faz referência compartilham o mesmo nome (
CountryId
). No entanto, isso não é um requisito – sua coluna de chave estrangeira pode ter um nome completamente diferente da coluna à qual ela faz referência (embora todas as colunas que participam de um relacionamento de chave estrangeira devam ser definidas com o mesmo comprimento e escala). Este exemplo faz com que o SQL Server gere automaticamente o nome da chave estrangeira. Isso porque eu não forneci um nome. Continue lendo para ver como você pode criar um nome para sua chave estrangeira.
Mas primeiro, vamos verificar a restrição de chave estrangeira que acabamos de criar.
Exemplo 3 – Verifique a restrição de chave estrangeira
Existem muitas maneiras de retornar uma chave estrangeira usando T-SQL, e aqui está uma delas:
EXEC sp_fkeys @fktable_name = City;
Resultado (usando saída vertical):
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 1 DELETE_RULE | 1 FK_NAME | FK__City__CountryId__38996AB5 PK_NAME | PK__Country__10D1609FC8BFA7F2 DEFERRABILITY | 7
As
sp_fkeys
O procedimento armazenado do sistema retorna informações sobre nossa chave estrangeira, sua chave primária associada e outros detalhes relevantes. Você simplesmente passa o nome da tabela de chave estrangeira ou da tabela de chave primária e ela retornará as informações relevantes. Neste exemplo, passo o nome da tabela de chave estrangeira –
City
. Nos resultados, podemos ver o
FK_NAME
coluna para ver se esta tabela tem uma restrição de chave estrangeira chamada
FK__City__CountryId__38996AB5
. Este é o que acabamos de criar. Agora que criamos a chave estrangeira, sempre que tentarmos inserir ou atualizar um valor no
City.CountryId
coluna, a restrição de chave estrangeira só permitirá se o mesmo valor já existir no Country.CountryId
coluna. Isso garante que a integridade referencial seja mantida no banco de dados. Exemplo 4 – Mais opções
É possível adicionar mais opções à sua definição de chave estrangeira.
Por exemplo, você pode fornecer um nome para a chave estrangeira. Você também pode especificar o que deve acontecer com os valores nesta coluna se o valor correspondente na chave primária for atualizado ou excluído.
Aqui, crio as duas tabelas novamente, mas desta vez especifico explicitamente essas opções (faço o mesmo para as chaves primárias):
CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_Country_CountryId PRIMARY KEY CLUSTERED (CountryId), CountryName nvarchar(60) ); CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_City_CityId PRIMARY KEY CLUSTERED (CityId), CountryId int NOT NULL, CONSTRAINT FK_City_Country FOREIGN KEY (CountryID) REFERENCES Country (CountryID) ON DELETE CASCADE ON UPDATE CASCADE, CityName nvarchar(60) );
Neste caso, a definição de chave estrangeira começa com
CONSTRAINT
, seguido pelo nome da chave estrangeira, seguido por FOREIGN KEY
, seguido pela coluna à qual a restrição de chave estrangeira será aplicada (inserida entre parênteses). Em seguida, vemos as mesmas
REFERENCES
cláusula que vimos no exemplo anterior. A
ON DELETE CASCADE
e ON UPDATE CASCADE
cláusulas são usadas para garantir que as alterações feitas em Country
tabela são propagadas automaticamente para a City
tabela. Por exemplo, se uma linha for excluída da tabela pai (chave primária), todas as linhas correspondentes serão excluídas da tabela de referência (chave estrangeira). O valor padrão para
ON DELETE
e ON UPDATE
é NO ACTION
. Nesse caso, o Mecanismo de Banco de Dados gera um erro e a ação de atualização ou exclusão na linha da tabela pai é revertida. Você também pode usar
SET NULL
para definir a coluna de chave estrangeira para NULL
(requer que a coluna de chave estrangeira seja anulável), ou SET DEFAULT
para defini-la com seu valor padrão (requer que a coluna de chave estrangeira tenha uma definição padrão. Se uma coluna for anulável e não houver um valor padrão explícito definido, NULL
torna-se o valor padrão implícito da coluna). Neste exemplo também aproveitei para nomear as chaves primárias. Você pode ver que a sintaxe da chave primária é semelhante à sintaxe da chave estrangeira, mas sem as
REFERENCES
cláusula (e com um CLUSTERED
adicionado argumento, que é o padrão para chaves primárias). Agora verifique a chave estrangeira:
EXEC sp_fkeys @fktable_name = City;
Resultado:
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 0 DELETE_RULE | 0 FK_NAME | FK_City_Country PK_NAME | PK_Country_CountryId DEFERRABILITY | 7
Podemos ver que o nome da chave estrangeira agora é FK_City_Country e a restrição de chave primária da coluna à qual ela faz referência é chamada de PK_Country_CountryId .
Exemplo 5 – Chave estrangeira em várias colunas
Você também pode criar uma chave estrangeira em várias colunas que fazem referência a uma chave primária de várias colunas. As chaves primárias de várias colunas também são conhecidas como chaves primárias compostas. Para criar uma chave estrangeira composta, basta separar as colunas com uma vírgula ao definir a chave.
Assim:
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
Consulte Como criar uma chave estrangeira composta no SQL Server para obter um exemplo mais detalhado.
A chave primária é realmente necessária?
Uma chave primária não é absolutamente necessária para chaves estrangeiras, pois você pode usar uma restrição exclusiva ou um índice exclusivo. Especificamente, a documentação da Microsoft afirma isso:
FOREIGN KEY
restrições podem referenciar apenas colunas emPRIMARY KEY
ouUNIQUE
restrições na tabela referenciada ou em umUNIQUE INDEX
na tabela referenciada.
Portanto, embora geralmente seja uma boa prática ter chaves primárias em todas as tabelas, suas chaves estrangeiras não são obrigadas a referenciá-las.