我编写了一个程序集中的CLR存储过程。
我有一个构建系统,可以从我们的源代码控制库自动构建和部署.net应用程序。
我希望这两件事能一起工作,这样我就可以重新部署承载CLR存储过程的程序集。
但是看起来,与IIS不同,只是替换二进制文件不起作用。看起来你必须对数据库进行DROP ASSEMBLY。为此,您需要删除引用该程序集的所有对象。
这在某种程度上似乎是合理的 - 即,从数据库完整性的角度来看 - 在另一种方式中是不合理的 - JIT方法适用于.NET的依赖关系的运行时评估。
那么,是否有可能做一些事情,所以我可以替换二进制文件,然后给SQL服务器一脚,让它弄清楚新程序集满足所有要求(即,具有正确的公共命名空间,类型,方法等来满足sprocs这是绑定它的)。
简短的回答是'不,它不会这样工作'。正如Remus指出的那样,SQL Server将程序集存储在数据库中,而不是文件系统中的某个位置。因此,没有这样的地方由服务器监控,你应该在哪里放置更新的二进制文件。
将更新的程序集上载到数据库应该是部署过程中不可或缺的一部分。并且这是明确执行以下操作的唯一方法:
实际上,步骤1可以通用方式在T-SQL中实现(因此您不必显式列出对象)。但除了自定义工具(它将使用反射以发现程序集内容并生成用于创建所有对象的适当T-SQL)之外,对于p.4没有这种方法。
CLR程序集存储在数据库中,而不是存储在磁盘上,因此您不能简单地替换某些二进制DLL。要刷新它们,请使用ALTER ASSEMBLY [assemblyname] FROM 'disklocation'
。
正如Remus's answer所述,您可以使用ALTER ASSEMBLY ...
更新程序集。
来自MSDN页面ALTER ASSEMBLY (Transact-SQL) for SQL Server 2008 R2 [强调我的]:
如果指定了FROM子句,则ALTER ASSEMBLY将根据提供的模块的最新副本更新程序集。由于在SQL Server实例中可能存在已针对程序集定义的CLR函数,存储过程,触发器,数据类型和用户定义的聚合函数,因此ALTER ASSEMBLY语句将它们重新绑定到程序集的最新实现。要完成此重新绑定,映射到CLR函数,存储过程和触发器的方法必须仍存在于具有相同签名的已修改程序集中。实现CLR用户定义类型和用户定义聚合函数的类仍必须满足作为用户定义类型或聚合的要求。
因此,如果引用程序集的函数,存储过程等没有更改,则只需更新程序集即可。此外,这样做不会中断当前正在运行的会话;从上面提到的同一个MSDN页面:
ALTER ASSEMBLY不会中断当前正在运行的会话,这些会话正在被修改的程序集中运行代码。当前会话通过使用程序集的未更改位来完成执行。
但是,您可以相当轻松地自动重新部署程序集及其依赖对象,但通常这样做,您需要删除并重新创建它。如果这样做,您可能会发现通过首先将汇编文件的字节转换为十六进制数字,然后将其包含在相关的CREATE ASSEMBLY
语句中,通过将它“嵌入”脚本来更容易部署程序集。
除了最后一句,我同意AlexS的建议。
首先,反射不会真正起作用,因为CLR函数中使用的数据类型不一定确定SQL数据类型。例如,您可以在CLR端使用SqlString,但在SQL端使用NVARCHAR(50)或NVARCHAR(MAX)而不是NVARCHAR(4000)。
但是,仍然可以自动执行此操作。您应该使用源代码存储库来存储指向CLR代码的存储过程和函数定义,就像存储任何存储过程或函数一样。因此,您可以获取所有这些定义并运行所有CREATE PROCEDURE和CREATE FUNCTION语句作为步骤4。
此外,步骤1和2可以是单个SQL脚本。
从本质上讲,整个过程可以自动化:)。