Как обновить сборку CLR без удаления сборки из SQL Server

18

Как я могу обновить сборку DLL функции (или процедуры) CLR без необходимости отбрасывать и заново создавать сборку в SQL Server (2008 R2)?

В настоящее время, если я обновляю сборку (например, чтобы добавить новую функцию), SQL Server не будет соблюдать обновленную DLL, пока я не урону сборку:

DROP ASSEMBLY CLRFunctions

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

Но прежде чем я могу удалить сборку, я должен сначала удалить все функции, которые на нее ссылаются:

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

И тогда я могу бросить сборку:

DROP ASSEMBLY CLRFunctions

Теперь мне нужно « создать » сборку:

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

И теперь я должен охотиться за декларацией всех UDF, которые были зарегистрированы, прежде чем я удалил их.

Я предпочел бы обновить сборку, и чтобы SQL Server начал ее использовать.


Обновление : я случайно попытался DBCC FREEPROCCACHEпринудительно «перекомпилировать», но SQL Server все еще использует старый код.

Обновление : я удалил сборку dll CLRFunctions.dll, и SQL Server все еще может выполнять код (без кода, который должен быть невозможным).

Ян Бойд
источник

Ответы:

16

Я думаю, что вы ищете alter assembly. От BOL:

Если указано предложение FROM, ALTER ASSEMBLY обновляет сборку в соответствии с последними копиями предоставленных модулей. Поскольку в экземпляре SQL Server могут быть функции CLR, хранимые процедуры, триггеры, типы данных и определяемые пользователем агрегатные функции, которые уже определены для сборки, оператор ALTER ASSEMBLY связывает их с последней реализацией сборки. Чтобы выполнить эту привязку, методы, которые отображаются на функции CLR, хранимые процедуры и триггеры, должны все еще существовать в измененной сборке с теми же сигнатурами. Классы, которые реализуют пользовательские типы CLR и пользовательские агрегатные функции, должны по-прежнему удовлетворять требованиям, предъявляемым к пользовательским типам или агрегатам.

Один из примеров на той же странице выглядит так:

ALTER ASSEMBLY ComplexNumber 
FROM 'C:\Program Files\Microsoft SQL Server\90\Tools\Samples\1033\Engine\Programmability\CLR\UserDefinedDataType\CS\ComplexNumber\obj\Debug\ComplexNumber.dll' 
Бен Тул
источник
1
Можно ли это сделать, когда обновленная сборка находится на клиентском компьютере SSMS, а не на хост-компьютере SQL Server? У меня недостаточно прав на сервере для прямого доступа к его файловой системе, но у меня достаточно прав для добавления и удаления сборок CLR.
Зарепет
Ну, в основном нет. Вы можете указать UNC-путь (т. Е. \\ server \ path \ to \ file), и если учетная запись службы, под которой работает ядро ​​SQL, имеет разрешения на чтение файла, она должна работать. Другой вариант - указать двоичное значение для сборки. Если он уже развернут на другом сервере, сценарий изменения оттуда даст вам значение BLOB-объекта.
Бен Тул
Да, я так и думал. :( Возможно, более новая версия SSMS позволит обновлять сборки с удаленного компьютера. Тем временем, я думаю, я удаляю и создаю сборки через графический интерфейс SSMS - и выполняю операции DROP и CREATE для всех зависимых функций.
Зарепет,
Я бы не стал задерживать дыхание на этом. Что касается необходимости удалить и воссоздать, почему вы не можете использовать любой из методов, описанных выше?
Бен Тул
1
«Добавление и изменение сборок требует ссылки на файловую систему». - это неправда. Оба CREATE ASSEMBLYи ALTER ASSEMBLYвозьмут блоб, представляющий сборку. Докажите это самим, перейдя в любую базу данных, созданную в 2008+, и перейдите в Программируемость -> Сборки и выполните сценарий создания сборки Microsoft.SqlServer.Types. Этот гигантский varbinary - это сборка . Поскольку это применимо к вашей ситуации, разверните вашу сборку в локальном экземпляре, запишите ее и сделайте ее ALTER ASSEMBLYсценарием.
Бен Тул
7

Чтобы добавить ответ Бен Тула, это можно сделать довольно легко удаленно через графический интерфейс SQL Server Management Studio .

  1. Под Обозревателем объектов для вашей базы данных -> Программируемость, щелкните правой кнопкой мыши на Сборках и выберите «Новая сборка ...».

  2. Перейдите к обновленной DLL.

  3. Вместо нажатия «ОК» (что не удастся, поскольку сборка с таким именем уже существует), нажмите «Сценарий» в верхней части окна «Новая сборка».
     
    Вы попадете в SQL-запрос, который содержит строку «CREATE ASSEMBLY», за которой следует огромный BLOB-объект - DLL, которую вы только что выбрали.

  4. Измените «CREATE» на «ALTER» и затем выполните!

Скрипт также создал для меня строку «АВТОРИЗАЦИЯ», которую мне пришлось удалить перед выполнением; Ваш пробег может варьироваться.

Я надеюсь, что это поможет кому-то еще без доступа файловой системы к своим серверам.

Надеюсь, Microsoft когда-нибудь сделает это первоклассной операцией в SSMS, но это довольно простой обходной путь, пока они этого не сделают.

Ф. Шинн
источник
1

я нашел подсказку в ответе на Stackoverflow :

ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Ян Бойд
источник
1
Вы имели в виду ALTER ASSEMBLY... ( UPDATEв DML, ALTERв DDL.)
miroxlav