如何在不从 SQL Server 中删除程序集的情况下更新 CLR 程序集

Ian*_*oyd 24 sql-server sqlclr sql-server-2008-r2

如何更新 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'.
Run Code Online (Sandbox Code Playgroud)

但在我可以删除程序集之前,我必须首先删除引用它的所有函数:

DROP FUNCTION NormalizeString
DROP FUNCTION RemoveDiacritics
DROP FUNCTION RemoveCombiningDiacritics
DROP FUNCTION CombineLigatures
....
DROP FUNCTION PseudolocalizeArabic
Run Code Online (Sandbox Code Playgroud)

并且然后我可以删除这个组件:

DROP ASSEMBLY CLRFunctions
Run Code Online (Sandbox Code Playgroud)

现在我必须“创建”程序集:

CREATE ASSEMBLY CLRFunctions FROM 'c:\foos\CLRFunctions.dll';
Run Code Online (Sandbox Code Playgroud)

现在我必须寻找的所有UDF的声明中之前,我删除了他们注册。

我宁愿更新程序集,并让 SQL Server 开始使用它。


更新:我随机尝试DBCC FREEPROCCACHE强制“重新编译”,但 SQL Server 仍然使用旧代码。

更新:我删除了程序集 dll CLRFunctions.dll,并且 SQL Server 仍然能够运行代码(没有应该不可能的代码)。

Ben*_*hul 20

我想你正在寻找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' 
Run Code Online (Sandbox Code Playgroud)

  • “添加和更改程序集需要文件系统引用。” - 这不是真的。“CREATE ASSEMBLY”和“ALTER ASSEMBLY”都将采用代表程序集的 blob。通过转到 2008+ 上创建的任何数据库并转到 Programmability -> Assemblies 并编写 Microsoft.SqlServer.Types 程序集的创建脚本来向自己证明这一点。那个巨大的 varbinary *就是程序集*。由于这适用于您的情况,请将程序集部署到本地实例,编写脚本,并将其设为“ALTER ASSEMBLY”脚本。 (2认同)

小智 10

添加到 Ben Thul 的答案中,这可以通过 SQL Server Management Studio 的 GUI远程轻松完成。

  1. 在数据库的 Object Explorer -> Programmability 下,右键单击 Assemblies 并选择“New Assembly...”。

  2. 浏览到您更新的 DLL。

  3. 不要单击“确定”(这将失败,因为同名程序集已存在)单击“新建程序集”窗口顶部的“脚本”。
     
    您将进入一个 SQL 查询,其中包含一个“CREATE ASSEMBLY”行,后跟一个巨大的 blob,即您刚刚选择的 DLL。

  4. 将“CREATE”更改为“ALTER”,然后执行!

该脚本还为我创建了一个“AUTHORIZATION”行,我必须在执行前将其删除;您的里程可能会有所不同。

我希望这可以帮助其他没有文件系统访问他们服务器的人。

希望微软有朝一日能将此作为 SSMS 中的一流操作,但在他们这样做之前,这是一个相当简单的解决方法。