Temos alguns códigos antigos em execução nos servidores Sql Server 2008 e estamos procurando atualizar para o Sql Server 2019. O código clr antigo é muito antigo (como .net framework 2.0 antigo), então eu sabia que teria que reconstruir o assemblies para o novo servidor. Fizemos um backup/restauração dos sistemas antigos para o novo sistema e, embora todos os assemblies estivessem lá, eles geraram erros na execução.
Eu encontrei as postagens "CLR strict security" e "CREATE ou ALTER ASSEMBLY para assembly XXX com a opção SAFE ou EXTERNAL_ACCESS falhou porque a opção 'clr strict security' de sp_configure está definida como 1. A Microsoft recomenda que você assine o assembly com um certificado..." mensagem.
Comecei na primeira montagem no primeiro db. Mudei o framework para 4.6.1 e assinei. Eu tentei ALTER ASSEMBLY pela primeira vez e ele disse que não poderia ALTER por causa da diferença de assinatura. Então eu eliminei todas as referências a esse assembly, então eliminei o assembly e fiz um CREATE ASSEMBLY com o novo código. E funcionou. Talvez não devesse, mas aconteceu.
Então eu comecei a trabalhar na próxima montagem no próximo banco de dados. Fez o mesmo processo (atualizar framework, assiná-lo, reconstruir, descartar todas as referências, descartar assembly, criar assembly). Somente na próxima vez que recebo "CREATE ou ALTER ASSEMBLY para assembly XXX com a opção SAFE ou EXTERNAL_ACCESS falhou porque a opção 'clr strict security' de sp_configure está definida como 1. A Microsoft recomenda que você assine o assembly com um certificado ..." mensagem.
eu corri
sp_configure
SELECT * FROM sys.trusted_assemblies
SELECT * FROM sys.assemblies
em ambos os bancos de dados. Ambos mostram "clr strict security" run_value como 1, ambos não mostram entradas em trusted_assemblies.
Estou percebendo que meu entendimento "apenas assine a montagem" não foi suficiente, mas estou intrigado por que a metodologia funcionou no primeiro banco de dados e falhou no segundo banco de dados.
Eu gerei os arquivos snk frescos para cada assembly e não associei nenhum login a eles.
Como "basta assinar a assembléia" conseguiu funcionar na primeira tentativa e não na segunda?
No primeiro banco de dados, na saída de sys.assemblies, vejo o token de chave pública da nova compilação no assembly e vejo SAFE_ACCESS no permission_set_desc e nas novas datas de instalação, mas não consigo descobrir por que isso foi suficiente em o primeiro db e não no segundo.
Obrigado
Primeiro, não há/há necessidade de recompilar os assemblies. Não importa que eles estivessem vinculados ao CLR 2.0. O SQL Server 2012 e mais recente (pelo menos até 2019) está vinculado apenas ao CLR 4.0 e, portanto, usará o nível mais alto do .NET Framework instalado nesse servidor na série 4.x. Isso funciona devido à compatibilidade com versões anteriores nas APIs do Framework.
Segundo, isso é realmente muito fácil de corrigir simplesmente assinando os assemblies no local. Dito de forma simples:
[master]
partir da chave pública de certificados do banco de dados atualUNSAFE ASSEMBLY
permissãoNada externo ao SQL Server é necessário. Eu tenho um exemplo disso na minha resposta para a seguinte pergunta (aqui no DBA.SE):
Mensagem de erro 10314, nível 16, estado 11 com assembly SAFE após a atualização para o SQL Server 2017
E no seguinte post:
SQLCLR vs. SQL Server 2017, Parte 4: “Assemblies confiáveis” – A decepção (Mensagem 10314)
Terceiro, não estou inteiramente certo por que suas ações funcionaram no primeiro caso, mas não no segundo, pois não deveria ter funcionado no primeiro caso. Se você não criou uma chave assimétrica
[master]
do assembly (ou o arquivo .snk usado para assinar/nomear fortemente esse assembly), a única maneira de carregar o assembly com êxito seria habilitar aTRUSTWORTHY
propriedade do banco de dados. É possível que você tenha feito isso em algum momento entre obter o erro original (o que não aconteceria seTRUSTWORTHY
estivesse ativado) e sua tentativa final deCREATE ASSEMBLY
?