sábado, 24 de janeiro de 2015

Duas maneiras de listar as chaves estrangeiras de um banco de dados

AS vezes precisamos listar todas as chaves estrangeiras de um banco de dados (e as tabelas/campos referenciados pelas mesmas). Tanto para automação de nosso mecanismo de persistência como para documentação do banco de dados.

Em algumas operações nós precisamos excluir todas as constraints, para fazer alguma manutenção ou inclusão desconsiderando-se a integridade referencial (geralmente ao passar dados de um banco para outro, cargas, restaurações etc), sendo estas recriadas depois.

A consulta pelas chaves estrangeiras pode ser feita usando-se as tabelas de sistema sysobjects e syscolumns ou as views de sistema INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS e INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE.

Usando sysobjects  e syscolumns

SELECT 
 o3.name 'Nome_Chave_Estrangeira', 
 o2.name 'Tabela',
 sc1.name 'Coluna (FK)',
 
 o1.name 'Tabela Referenciada',
 sc2.name 'Coluna Referenciada (PK)'foreign key ('+sc1.name+') references '+o1.name+'('+sc2.name+')'  
FROM 
 sysforeignkeys fk 
 INNER JOIN sysobjects o1 on o1.id = fk.rkeyid --para obter a cahve estrangeira e a tabela referenciada
 INNER JOIN sysobjects o2 on o2.id = fk.fkeyid --tabla de objetos e campo da chave pk
 inner join sysobjects o3 on o3.id = fk.constid --tabela de objetos e campo da constraint (constid) para pegar o  nome da constraint
 inner join syscolumns sc1 on sc1.id = fk.fkeyid and sc1.colid = fk.fkey  --coluna pk
 inner join syscolumns sc2 on sc2.id = fk.rkeyid and sc2.colid = fk.rkey  --coluna referenciada fk
where 
 o1.name = 'company'

Usando views de sistema.


SELECT
    rc.CONSTRAINT_NAME 'Nome_Chave_Estrangeira',     
    rcu.TABLE_NAME 'Tabela', 
    rcu.COLUMN_NAME 'Coluna (FK)',
    rcu1.TABLE_NAME 'Tabela Referenciada',
    rcu1.COLUMN_NAME 'Coluna Referenciada (PK)'
FROM
    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
INNER JOIN 
    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE rcu 
      ON rc.CONSTRAINT_CATALOG = rcu.CONSTRAINT_CATALOG 
         AND rc.CONSTRAINT_NAME = rcu.CONSTRAINT_NAME
INNER JOIN 
    INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE rcu1 
      ON rc.UNIQUE_CONSTRAINT_CATALOG = rcu1.CONSTRAINT_CATALOG 
         AND rc.UNIQUE_CONSTRAINT_NAME = rcu1.CONSTRAINT_NAME

where rcu1.TABLE_NAME = 'company'

Podemos notar que usando as views de sistema nosso filtro é mais simples, mas usando sysobjects e syscolumns  temos mais flexibilidade no que queremos trazer.

Você pode fazer uma consulta gerar, como string/varchar, o código necessário para exclui todas as suas constraints, caso existam, e recriar todas elas, caso não existam, mas atenção: se alguma das suas constraints tiver políticas diferentes quanto ao "on update cascade" ou "on delete cascade" você simplesmente não pode excluí-las e recriá-las assim, em massa.

SELECT 
 o3.name 'Nome_Chave_Estrangeira', 
 o2.name 'Tabela',
 sc1.name 'Coluna (FK)',
 
 o1.name 'Tabela Referenciada',
 sc2.name 'Coluna Referenciada (PK)',
 
 
 'IF  EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'''+o3.name+''') AND parent_obj = OBJECT_ID(N'''+o2.name+''')) ALTER TABLE '+o2.name+' DROP CONSTRAINT ['+o3.name+']',
 'IF  not EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID(N'''+o3.name+''') AND parent_obj = OBJECT_ID(N'''+o2.name+''')) ALTER TABLE '+o2.name+' add CONSTRAINT ['+o3.name+'] foreign key ('+sc1.name+') references '+o1.name+'('+sc2.name+')'  
FROM 
 sysforeignkeys fk 
 INNER JOIN sysobjects o1 on o1.id = fk.rkeyid --para obter a cahve estrangeira e a tabela referenciada
 INNER JOIN sysobjects o2 on o2.id = fk.fkeyid --tabla de objetos e campo da chave pk
 inner join sysobjects o3 on o3.id = fk.constid --tabela de objetos e campo da constraint (constid) para pegar o  nome da constraint
 inner join syscolumns sc1 on sc1.id = fk.fkeyid and sc1.colid = fk.fkey  --coluna pk
 inner join syscolumns sc2 on sc2.id = fk.rkeyid and sc2.colid = fk.rkey  --coluna referenciada fk
where 
 o1.name = 'company'


Esse link foi de grande ajuda para identificar todas as chaves estrangeiras de uma tabela

Have Fun :)

Nenhum comentário:

Postar um comentário

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)