Gostaria de usar o código que desenvolvi no C # CLR para ser usado em todos os bancos de dados no sistema, para que não seja necessário definir cada um como confiável, ativar o CLR e manter um monte de código dentro de cada um .
Existe uma maneira melhor de fazer isso do ponto de vista administrativo e de segurança? As funções CLR são muito básicas, como disjuntores, validação de email, url en / decode, base64 e etc. Gostaria apenas que o esquema dbo em cada banco de dados pudesse acessar as funções.
- Existe alguma maneira simples de fazer isso?
- Também não estou claro se a dll CLR está incorporada e se eu mover o banco de dados, ele será marcado junto, ou eu tenho que movê-la também.
obrigado
sql-server
sql-server-2008
sql-server-2008-r2
c#
sql-clr
Alex Erwin
fonte
fonte
Respostas:
Na nossa empresa, temos essa configuração exata. Quando você cria um assembly CLR, uma representação binária do assembly é armazenada no banco de dados em que você o cria. Isso permite que você o leve com você (e até faça um script), caso você mova o banco de dados a qualquer momento.
Alguns meses atrás, nosso data center foi inundado - enchendo vários servidores cheios de água. Quando os reconstruí, usei apenas os backups do banco de dados que haviam sido feitos na noite anterior. Até agora, não tivemos problemas .. (toque na madeira!)
Não tenho certeza se isso é a coisa certa a ser feita do ponto de vista da segurança, mas a maneira como concedemos acesso aos procs do CLR etc é criar uma função no banco de dados compartilhado e adicionar usuários de outros bancos de dados a essa função. A função é então concedida para executar nos procs do CLR.
Pode haver problemas de acesso se o CLR estiver tentando fazer coisas como acessar recursos fora do banco de dados em que está contido, mas você pode definir a permissão no assembly ao criá-lo. O link abaixo tem muito mais informações sobre permissões do que posso explicar aqui:
http://msdn.microsoft.com/en-us/library/ms345101.aspx
Espero que isso ajude você.
fonte
O binário do assembly é armazenado como um blob no banco de dados, portanto é transportado para onde quer que o banco de dados vá. O CLR está ativado apenas na instância - não há configurações específicas do banco de dados para isso.
De qualquer forma, por que você está tentando fazer isso?
(Não estou tentando argumentar; só quero ouvir os motivos envolvidos, porque talvez o problema possa ser resolvido de uma maneira diferente que atenda às suas necessidades.)
Não há como fazer isso facilmente, exceto colocar o assembly em um banco de dados compartilhado.
Dito isso, acho que é vantajoso adotar a arquitetura centrada em banco de dados, a menos que exista uma situação específica que tenha razões muito convincentes para centralizar. O motivo é que colocar o assembly (ou qualquer outra coisa) fora do banco de dados cria uma dependência em seu ambiente. Essa é precisamente a abordagem oposta que a Microsoft está adotando nos bancos de dados contidos a partir do SQL Server 2012.
Quando você começa a precisar usar recursos como replicação ou cluster, essa dependência pode potencialmente adicionar uma quantidade enorme de complexidade à implantação, mas também à solução de problemas e procedimentos de failover.
Essa arquitetura é muito menos óbvia para as pessoas que não estão familiarizadas com o sistema (ou seja, é menos auto-detectável e menos documentada).
Se você acabar exigindo segurança diferente em bancos de dados diferentes ou qualquer coisa que envolva variação, estará em um mundo de ferimentos.
Se esses bancos de dados forem implantados para os clientes (parece que não serão, mas vou dizer isso por completo), isso adiciona complexidade ao procedimento, manutenção e solução de problemas de implantação.
Como todos os bancos de dados compartilhariam esse código, se algum erro fosse introduzido (ou corrigido!), Isso poderia interromper todos os aplicativos que dependem dos bancos de dados. O teste de unidade abrangente seria uma necessidade absoluta.
Se você possui vários bancos de dados que precisam da mesma funcionalidade, existem outras maneiras de reduzir a quantidade de duplicação envolvida, que eu assumo ser o objetivo do exercício. Mesmo um assembly CLR bastante complexo não ocupa muito espaço de armazenamento físico em comparação com os dados no próprio banco de dados (quase sempre), por isso não vejo isso como um argumento válido, a menos que você tenha literalmente milhares de pequenos bancos de dados que precisam disso. montagem.
O que você pode fazer é modificar outras partes do procedimento de implantação desses bancos de dados para reduzir a duplicação de origem. Por exemplo, crie e implante o assembly a partir do local comum do código CLR no controle de origem. Ou crie um script que implante o mesmo assembly nos bancos de dados. Automatize essa parte das coisas o máximo possível, e não será grande coisa.
Concordo que o que estou sugerindo é uma troca, porque ainda haverá alguma duplicação, mas isso deve ser equilibrado com os negativos envolvidos na implementação de uma arquitetura que não segue o padrão prescrito. Somente você pode decidir o que é certo para o seu ambiente.
fonte
Como as outras duas respostas afirmam corretamente, os assemblies são carregados em um banco de dados específico e não são de todo o sistema (embora eu esteja bastante certo de que o
assembly_id
valor é único em todo o sistema). Isso significa que eles são copiados e restaurados com cada banco de dados em que são carregados.Além disso, a configuração
enabled
/disabled
deCLR Integration
(viasp_configure
) é de todo o sistema. Como uma observação lateral, essa configuração é apenas para a funcionalidade CLR criada pelo usuário ; Em geral, o CLR é sempre ativado, pois certas funcionalidades internas dependem disso.Dito isto, embora as outras duas respostas aqui apresentem pontos válidos, esses pontos não são específicos ao SQLCLR e não há menção dos fatores na tomada dessa decisão que são específicos ao código do SQLCLR. Há problemas de memória a serem considerados se você implantar código em cada banco de dados individual (supondo que você tenha muitos bancos de dados), possíveis problemas de contenção de recursos, possíveis problemas relacionados à segurança etc.
Forneci o que deveria ser uma lista abrangente de itens a serem lembrados, especificamente para o código SQLCLR, ao decidir entre um banco de dados centralizado e uma implantação de banco de dados individual. Em vez de duplicar a lista aqui, consulte a seguinte resposta (também aqui no DBA.SE):
Como usar melhor a função CLR do ponto de vista do desempenho (repita dentro de cada banco de dados ou tenha função geral)?
Além disso, em uma nota relacionada, eu questionaria por que qualquer banco de dados está sendo definido
TRUSTWORTHY ON
. A funcionalidade observada na pergunta (ou seja, "separadores de seqüência de caracteres, validação de email, url en / decode, base64, etc") é possível em umSAFE
assembly. Você não deve usar os valoresEXTERNAL_ACCESS
ouUNSAFE
perission_set, a menos que seja absolutamente necessário. E se for necessário para um certo número de funções, elas devem estar em um Assembly separado que contenha apenasSAFE
código, para que quaisquer funções escalares que não acessam dados e sejam marcadas comoIsDeterministic = true
possam aproveitar o benefício de desempenho de serem capaz de participar de planos paralelos.fonte