Olá pessoal,
Bom dia!
Introduction
Neste post vou demonstrar para vocês como identificar, apagar e recriar Foreign Keys (FK) de uma tabela no SQL Server. Muitas vezes precisamos excluir uma tabela ou apenas alterar uma coluna, mas o banco nos envia uma mensagem de erro informando que existe uma constraint de chave estrangeira para essa coluna, impossibilitando o DBA de realizar a alteração solicitada.
Msg 5074, Level 16, State 1, Line 57
The object ‘PK__Clientes__3214EC07F3BD01EC’ is dependent on column ‘Id’.
Msg 5074, Level 16, State 1, Line 57
The object ‘FK_Cliente_Telefone’ is dependent on column ‘Id’.
Msg 5074, Level 16, State 1, Line 57
The object ‘FK_Cliente_Endereco’ is dependent on column ‘Id’.
Msg 4922, Level 16, State 9, Line 57
ALTER TABLE ALTER COLUMN Id failed because one or more objects access this column.
Para resolver esse problema, deve-se remover as contraints de FK, realizar a alteração na tabela e depois criar novamente. Quando a tabela possui muitas referências, essa tarefa se torna um pouco trabalhosa, principalmente se várias tabelas estão envolvidas.
Para facilitar essa atividade, que é bem comum no dia a dia, resolvi criar e disponibilizar para vocês, uma Stored Procedure que verifica as FK’s nas views de catálogo do SQL Server e traz a listagem completa.
Importante: Por restrição técnica, o SQL Server permite criar Foreign Keys apenas entre objetos do mesmo database.
Criando a massa de testes
Para demonstrar a utilização dessa procedure, criei esse script simples para que você gere uma massa de testes e possa testar a SP.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
IF (OBJECT_ID('dbo.Clientes') IS NOT NULL) DROP TABLE dbo.Clientes CREATE TABLE dbo.Clientes ( Id INT IDENTITY(1,1) PRIMARY KEY, Name VARCHAR(50) ) INSERT INTO dbo.Clientes SELECT 'Dirceu' UNION ALL SELECT 'Patricia' UNION ALL SELECT 'Lucas' UNION ALL SELECT 'Leandro' UNION ALL SELECT 'Richardson' IF (OBJECT_ID('dbo.Enderecos') IS NOT NULL) DROP TABLE dbo.Enderecos CREATE TABLE dbo.Enderecos ( Id INT IDENTITY(1,1) PRIMARY KEY, Id_Cliente INT, Ds_Endereco VARCHAR(50) ) ALTER TABLE dbo.Enderecos ADD CONSTRAINT FK_Cliente_Endereco FOREIGN KEY (Id_Cliente) REFERENCES dbo.Clientes(Id) INSERT INTO dbo.Enderecos (Id_Cliente, Ds_Endereco) SELECT 1, 'Endereço Teste Cliente 1' UNION ALL SELECT 2, 'Endereço Teste Cliente 2' UNION ALL SELECT 3, 'Endereço Teste Cliente 3' IF (OBJECT_ID('tempdb..dbo.Telefones') IS NOT NULL) DROP TABLE dbo.Telefones CREATE TABLE dbo.Telefones ( Id INT IDENTITY(1,1) PRIMARY KEY, Id_Cliente INT, Nr_Telefone VARCHAR(11) ) ALTER TABLE dbo.Telefones ADD CONSTRAINT FK_Cliente_Telefone FOREIGN KEY (Id_Cliente) REFERENCES dbo.Clientes(Id) INSERT INTO dbo.Telefones (Id_Cliente, Nr_Telefone) SELECT 1, '27999998888' UNION ALL SELECT 4, '27999997777' UNION ALL SELECT 5, '27999996666' IF (OBJECT_ID('dbo.Teste1') IS NOT NULL) DROP TABLE dbo.Teste1 CREATE TABLE dbo.Teste1 ( Cod1 INT NOT NULL, Cod2 int NOT NULL, Cod3 int NOT NULL, Name VARCHAR(200) ) IF (OBJECT_ID('dbo.Teste2') IS NOT NULL) DROP TABLE dbo.Teste2 CREATE TABLE dbo.Teste2 ( Codigo1 INT NOT NULL, Codigo2 int NOT NULL, Codigo3 int NOT NULL, Name VARCHAR(200) ) ALTER TABLE dbo.Teste2 ADD CONSTRAINT [PK_Teste2] PRIMARY KEY (Codigo1, Codigo2, Codigo3) ALTER TABLE dbo.Teste1 ADD CONSTRAINT [FK_Teste1] FOREIGN KEY (Cod1, Cod2, Cod3) REFERENCES dbo.Teste2(Codigo1, Codigo2, Codigo3) |
Como Remover as FK’s que Referenciam uma Tabela
Com o código abaixo, você poderá criar a SP citada no tópico, que permite a fácil visualização das FK’s que referenciam uma determinada tabela, e já informa o script para a remoção e criação dessa FK:
Agora vamos dar uma olhada no resultado:
Lembrando que quando você for apagar as FK’s, copie ANTES os scripts para gerar novamente. Uma vez que as FK’s forem removidas, você não irá conseguir gerar novamente esses scripts utilizando a SP.
Como Remover as FK’s que referenciam uma tabela (FK composta)
Com a procedure abaixo, você pode facilmente identificar e remover/recriar as FK’s de uma determinada tabela, que possuem referências de chaves estrangeiras para outros objetos, mesmo que utilizem uma chave composta (mais de uma coluna formando a FK).
Visualizar código-fonteComo Remover as FK’s de uma tabela
Com a procedure abaixo, você pode facilmente identificar e remover/recriar as FK’s de uma determinada tabela, que possuem referências de chaves estrangeiras para outros objetos.
Visualizar código-fonteAnd that's it, folks!
Até a próxima!
Script da FK composta com problema ao executar que não retorna consulta. Resolvido editando e colocando o select para setar em @query e não em @cmd.
Obrigado pela dica Neemias, já fiz a correção no script. Obrigado 🙂
Script muito útil principalmente pra quem tem que fazer carga de dados no dia a dia . Muito grato por essa excelente postagem.