Sql server 重新部署包含CLR存储过程的.NET程序集

Sql server 重新部署包含CLR存储过程的.NET程序集,sql-server,stored-procedures,deployment,continuous-integration,sqlclr,Sql Server,Stored Procedures,Deployment,Continuous Integration,Sqlclr,我已经在程序集中编写了一个CLR存储过程 我有一个构建系统,可以从我们的源代码管理存储库自动构建和部署.net应用程序 我希望这两件事一起工作,这样我就可以重新部署承载CLR存储过程的程序集 然而,与IIS不同,简单地替换二进制文件是行不通的。看起来您必须在数据库上删除程序集。为了做到这一点,您需要删除引用该部件的所有对象 这在某种程度上似乎是合理的——也就是说,从数据库完整性的角度来看——而在另一方面似乎是不合理的——一般来说,JIT方法适用于.NET依赖项的运行时评估 那么,有没有可能做点什

我已经在程序集中编写了一个CLR存储过程

我有一个构建系统,可以从我们的源代码管理存储库自动构建和部署.net应用程序

我希望这两件事一起工作,这样我就可以重新部署承载CLR存储过程的程序集

然而,与IIS不同,简单地替换二进制文件是行不通的。看起来您必须在数据库上删除程序集。为了做到这一点,您需要删除引用该部件的所有对象

这在某种程度上似乎是合理的——也就是说,从数据库完整性的角度来看——而在另一方面似乎是不合理的——一般来说,JIT方法适用于.NET依赖项的运行时评估


那么,有没有可能做点什么来替换二进制文件,然后给SQL server一个提示,让它知道新程序集满足所有要求(即,有正确的公共名称空间、类型、方法等来满足绑定到它的存储过程)。

CLR程序集存储在数据库中,而不是磁盘上,因此,您不能简单地替换一些二进制dll。要刷新它们,请从“disklocation”使用
ALTER ASSEMBLY[assemblyname]

简短的回答是“不,它不会以这种方式工作”。正如Remus所指出的,SQLServer将程序集存储在数据库中,而不是文件系统中的某个位置。因此,没有这样的地方是由服务器监控的,您应该在那里放置更新的二进制文件

将更新的程序集上载到数据库应该是部署过程中不可或缺的一部分。唯一的方法是明确执行以下操作:

  • 删除程序集中定义的所有对象(即所有外部SP/UDF/触发器/类型)
  • 下降组件
  • 创建程序集-使用“FROM'disklocation'”或“FROM'binary content'”创建程序集(如Remus所建议,但请注意,路径应指SQL Server的本地路径)
  • 创建所有[外部]对象

  • 步骤1实际上可以以一种通用的方式在T-SQL中实现(因此您不必显式地列出对象)。但是除了自定义工具(它将使用反射来发现程序集内容并生成用于创建所有对象的适当T-SQL)之外,p.4没有这种方法。

    除了最后一句之外,我同意亚历克斯的建议

    首先,反射不会真正起作用,因为CLR函数中使用的数据类型不一定决定SQL数据类型。例如,您可以在CLR端使用SqlString,但在SQL端使用NVARCHAR(50)或NVARCHAR(MAX)而不是NVARCHAR(4000)

    但是,仍然可以将其自动化。您应该使用源代码存储库来存储指向CLR代码的存储过程和函数定义,就像存储任何过程或函数一样。因此,您可以获取所有这些定义,并在步骤4中运行所有创建过程和创建函数语句

    此外,步骤1和2可以是单个SQL脚本

    基本上,整个过程可以自动化:)。

    作为状态,您可以使用
    更改程序集…
    来更新程序集

    从MSDN页面[强调我的]:

    如果指定了FROM子句,ALTER ASSEMBLY将根据所提供模块的最新副本更新程序集。由于SQL Server实例中可能存在已针对程序集定义的CLR函数、存储过程、触发器、数据类型和用户定义的聚合函数,ALTER assembly语句将它们重新绑定到程序集的最新实现要完成此重新绑定,映射到CLR函数、存储过程、,和触发器必须仍然存在于具有相同签名的修改程序集中。实现CLR用户定义类型和用户定义聚合函数的类必须仍然满足作为用户定义类型或聚合的要求

    因此,如果引用程序集的函数、存储过程等没有更改,您可以简单地更新程序集。而且,这样做不会中断当前正在运行的会话;从上述相同的MSDN页面:

    ALTER ASSEMBLY不会中断正在修改的程序集中运行代码的当前正在运行的会话。当前会话通过使用程序集的不变位来完成执行


    但是,您可以相当轻松地自动重新部署程序集及其依赖对象,但通常需要删除并重新创建它。如果这样做,您可能会发现通过将程序集文件的字节首先转换为十六进制数字,然后将其包含在相关的
    CREATE assembly
    语句中,通过将程序集“嵌入”到脚本中,可以更容易地部署程序集。

    “步骤1实际上可以以通用方式在T-SQL中实现”-如何才能做到这一点?最简单的方法是什么?“但第4页除了自定义工具外没有其他方法”-您知道任何此类工具的名称吗?@tbone,它知道[1]和[2]。对于[4],我使用了一个数据库构建/比较/模式同步工具,因此我在数据库的版本控制项目/存储库中为每个“外部”对象创建了一个T-SQL拖放脚本。数据库工具有效地运行了所有这些脚本,因此我没有使用使用使用反射的工具来自动发现程序集中的CLR对象。这是对完整更新过程的一个很好的描述,但我认为OP实际上会问,如果所有函数/过程签名都保持不变,我们是否只能更新程序集。。。这只会发生在alterassembly上。