Como atualizar um assembly CLR sem soltar o assembly do SQL Server

18

Como atualizar uma dll de assembly de função (ou procedimento) do CLR sem precisar soltar e recriar o assembly no SQL Server (2008 R2)?

Como está agora, se eu atualizar um assembly (por exemplo, para adicionar uma nova função), o SQL Server não honrará a dll atualizada até eu largar o assembly:

DROP ASSEMBLY CLRFunctions

Msg 6590, Level 16, State 1, Line 1
DROP ASSEMBLY failed because 'CLRFunctions' is referenced by object 'NormalizeString'.

Mas antes que eu possa descartar o assembly, devo primeiro descartar todas as funções que o referenciam:

DROP FUNCTION NormalizeString
DROP FUNCTION RemoveDiacritics
DROP FUNCTION RemoveCombiningDiacritics
DROP FUNCTION CombineLigatures
....
DROP FUNCTION PseudolocalizeArabic

E então eu posso largar a montagem:

DROP ASSEMBLY CLRFunctions

Agora eu tenho que " criar " a montagem:

CREATE ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';

E agora eu tenho que caçar a declaração de todas as UDFs que foram registradas antes de excluí-las.

eu prefiro atualizar um assembly e fazer com que o SQL Server comece a usá-lo.


Atualização : tentei aleatoriamente DBCC FREEPROCCACHEforçar uma "recompilação", mas o SQL Server ainda usa o código antigo.

Atualização : excluí a dll do assembly CLRFunctions.dlle o SQL Server ainda pode executar o código (sem o código que deveria ser impossível).

Ian Boyd
fonte

Respostas:

16

Eu acho que você está procurando alter assembly. Partida BOL:

Se a cláusula FROM for especificada, ALTER ASSEMBLY atualiza o assembly com relação às cópias mais recentes dos módulos fornecidos. Como pode haver funções CLR, procedimentos armazenados, gatilhos, tipos de dados e funções agregadas definidas pelo usuário na instância do SQL Server que já estão definidas no assembly, a instrução ALTER ASSEMBLY os vincula à implementação mais recente do assembly. Para realizar essa religação, os métodos que são mapeados para funções, procedimentos armazenados e gatilhos CLR ainda devem existir no assembly modificado com as mesmas assinaturas. As classes que implementam tipos definidos pelo usuário CLR e funções agregadas definidas pelo usuário ainda devem satisfazer os requisitos para serem um tipo ou agregado definido pelo usuário.

Um dos exemplos na mesma página parece ter funcionado:

ALTER ASSEMBLY ComplexNumber 
FROM 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\1033\Engine\Programmability\CLR\UserDefinedDataType\CS\ComplexNumber\obj\Debug\ComplexNumber.dll' 
Ben Thul
fonte
11
Isso pode ser feito quando o assembly atualizado está localizado na máquina cliente do SSMS e não na máquina host do SQL Server? Não tenho privilégios suficientes no servidor para acessar diretamente seu sistema de arquivos, mas tenho direitos suficientes para adicionar e remover assemblies CLR.
Zarepheth 06/11
Não. Bem, principalmente não. Você pode especificar um caminho UNC (por exemplo, \\ servidor \ caminho \ para \ arquivo) e, desde que a conta de serviço na qual o mecanismo SQL esteja executando tenha permissões de leitura no arquivo, ela funcione. A outra opção é especificar o valor binário para a montagem. Se você já o tiver implantado em outro servidor, o script da alteração a partir daí obterá o valor do blob.
Ben Thul
Sim, foi o que eu pensei. :( Talvez uma versão mais recente do SSMS permita a atualização de assemblies de uma máquina remota. Enquanto isso, acho que deixo de lado e crio assemblies através da GUI do SSMS - e
realizo
Eu não prenderia a respiração nessa. Quanto a abandonar e recriar, por que você não pode exercitar nenhum dos métodos descritos acima?
Ben Thul
11
"Adicionar e alterar montagens requer uma referência ao sistema de arquivos." - isso não é verdade. Ambos CREATE ASSEMBLYe ALTER ASSEMBLYterão um blob que representa a montagem. Prove isso você mesmo, acessando qualquer banco de dados criado em 2008+ e vá para Programmability -> Assemblies e crie um script para criar o assembly Microsoft.SqlServer.Types. Esse varbinário gigantesco é a assembléia . Como isso se aplica à sua situação, implemente seu assembly na instância local, faça um ALTER ASSEMBLYscript e faça um script.
quer
7

Para adicionar à resposta de Ben Thul, isso pode ser realizado remotamente com bastante facilidade via GUI do SQL Server Management Studio .

  1. No Pesquisador de objetos do seu banco de dados -> Programação, clique com o botão direito do mouse em Assemblies e selecione 'New Assembly ...'.

  2. Vá para a sua DLL atualizada.

  3. Em vez de clicar em 'OK' (que falhará, pois já existe uma montagem com o mesmo nome), clique em 'Script' na parte superior da janela Nova montagem.
     
    Você será inserido em uma Consulta SQL que inclui uma linha 'CREATE ASSEMBLY' seguida por um enorme blob que é a DLL que você acabou de selecionar.

  4. Mude 'CREATE' para 'ALTER' e depois execute!

O script também criou uma linha de 'AUTORIZAÇÃO' para mim que eu precisei remover antes de executar; sua milhagem pode variar.

Espero que isso ajude alguém sem acesso do sistema de arquivos aos seus servidores.

Espero que a Microsoft faça disso uma operação de primeira classe no SSMS algum dia, mas essa é uma solução bastante fácil até que eles o façam.

F. Shinn
fonte
1

Encontrei uma dica para a resposta no Stackoverflow :

ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Ian Boyd
fonte
11
Você quis dizer ALTER ASSEMBLY... ( UPDATEestá no DML, ALTERestá na DDL.)
miroxlav