6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr

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 :)

Comentários

Postagens mais visitadas deste blog

Factory Reset do Samsung Galaxy S

erro "ora-12154: tns: não foi possível resolver o identificador de conexão especificado"

Detectar o encoding de um arquivo para não corromper ao transformá-lo