Olá pessoal,
Bom dia!

Introdução

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.

IF (OBJECT_ID('dbo.Clientes') IS NOT NULL) DROP TABLE dbo.Clientes
CREATE TABLE dbo.Clientes (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Nome 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,
    Nome 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,
    Nome 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)