Um dos meus desenvolvedores escreveu uma função SQL que funciona como a função VB.Net (LastIndexOf) e deseja publicá-la. Minha pergunta é qual seria o motivo de colocar isso em um banco de dados central em vez de colocá-lo em cada banco de dados do usuário?
O desenvolvedor estava tentando colocá-lo no esquema sys em seu banco de dados mestre para que ele não tivesse que qualificar chamadas para ele dos bancos de dados do usuário ... suspiro
Mas eu não tinha certeza de qual seria a desculpa válida para centralizá-lo (obviamente não o banco de dados mestre) em relação ao banco de dados de cada usuário?
A maneira que eu prefiro fazer: colocar a função em um banco de dados utilitário e criar um sinônimo para ela em cada banco de dados regular. Dessa forma, você obtém o melhor dos dois mundos:
por exemplo
Isso é especialmente poderoso para funções CLR, pois há sobrecarga administrativa extra para alterá-las/implementá-las.
E isso é preferível a usar mestre (e marcar como um objeto do sistema, que não é garantido como portátil). Eu adoraria saber como seu desenvolvedor espera criar sua função no
sys
esquema.Eu entendo que manter várias cópias de uma função em 500 bancos de dados não é mais difícil do que manter uma única cópia, mas ter várias cópias é realmente apenas um benefício quando você tem exceções (por exemplo, o cliente A deseja que sua função lide com NULLs de maneira diferente, ou alguma coisa). Nesse caso, eu deixaria o sinônimo em todos os outros bancos de dados e introduziria uma versão especial da função apenas naquele banco de dados.
(Isso pressupõe que a função não depende de nenhum acesso a dados no banco de dados de um cliente, é claro - o que certamente pode complicar as coisas.)
Vou ter que discordar de Aaron (e da resposta aceita).
A abordagem de Aaron é a maneira como gosto de lidar com "coisas de DBA", por exemplo, scripts de manutenção. Eu nunca gostaria de fazer isso com uma função de biblioteca que seria chamada por um banco de dados do usuário.
Por quê? Você estará indo para o banco de dados equivalente ao DLL Hell .
Instale o .net 4.5 em um servidor executando um aplicativo .net 2.0 e o que acontece? Nada, seu aplicativo continua a usar a estrutura 2.0. Atualize sua função LastIndexOf em um servidor que hospeda 3 bancos de dados de aplicativos (como parte de uma atualização para um deles) e o que acontece? Todos os três agora estão usando a versão mais recente.
A alternativa é a abordagem adotada pelo SQL# . Isso é instalado em um esquema em cada banco de dados do usuário, para que você possa atualizar com segurança o banco de dados para o Application-X sem arriscar a estabilidade do Application-Y.
Se você estiver trabalhando em um ambiente de gerenciamento de alterações rigidamente controlado, não terá escolha, pois não poderá atualizar um componente compartilhado sem testar todos os consumidores do componente. Se você está trabalhando em algum lugar um pouco mais "rápido e solto", você está livre para correr o risco de quebrar algo involuntariamente com um patch/upgrade.
A resposta a esta pergunta depende se estamos falando de objetos T-SQL ou objetos SQLCLR. Existem diferentes (e mais) fatores a serem considerados ao lidar com objetos SQLCLR.
Em termos de objetos T-SQL, ambas as respostas aqui trazem pontos válidos. Conforme descrito na resposta de @Aaron, o banco de dados central pode ser bastante útil e os sinônimos podem ser usados para facilitar que alguns bancos de dados apontem para o recurso compartilhado e alguns usem um recurso local. Mas o ponto levantado na resposta de Mark sobre o aumento do risco devido à dependência mais forte não pode ser ignorado.
No entanto, se você estiver lidando com objetos SQLCLR, primeiro precisará considerar todos os pontos que levantei na seguinte resposta:
Como usar melhor a função CLR do ponto de vista do desempenho (repita dentro de cada banco de dados ou tenha uma função geral)?