如何更新 CLR 函数(或过程)程序集 dll,而不必在 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 仍然能够运行该代码(没有代码这是不可能的)。
答案1
我认为您正在寻找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'
答案2
除了 Ben Thul 的回答之外,这可以相当轻松地远程完成通过 SQL Server Management Studio 的 GUI。
在数据库的对象资源管理器->可编程性下,右键单击程序集并选择“新建程序集...”。
浏览到更新的 DLL。
不要单击“确定”(这将失败,因为同名的程序集已经存在),而是单击“新建程序集”窗口顶部的“脚本”。
您将进入一个 SQL 查询,其中包含一行“CREATE ASSEMBLY”,后面跟着一个巨大的 blob,即您刚刚选择的 DLL。将‘CREATE’改为‘ALTER’然后执行!
该脚本还为我创建了一条“授权”行,我必须在执行之前将其删除;您的里程可能会有所不同。
我希望这可以帮助那些没有文件系统访问权限的人访问他们的服务器。
希望微软有一天能把这变成 SSMS 中的一流操作,但在他们这样做之前,这是一个相当简单的解决方法。
答案3
我找到了答案的提示堆栈溢出:
ALTER ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';