使用文件路径在UNSAFE模式下创建汇编不会在数据库中创建函数

时间:2015-05-08 05:01:20

标签: sql sql-server sql-server-2012 sqlclr

我正在尝试使用以下语句在SQL Server中注册CLR程序集:

CREATE ASSEMBLY SQLCLRTest
AUTHORIZATION [dbo]
FROM 'C:\MyApp\SQLCLRTest.dll'
WITH PERMISSION_SET = UNSAFE;

CLR程序集使用pfx密钥签名,我已经创建了一个非对称密钥和SQL登录,以允许安装此特定程序集并设置了UNSAFE权限。

问题是上面的语句在数据库中创建了程序集,但它没有显示我在程序集中创建的任何sql server函数。

我没有看到我的CLR程序集有任何问题,因为当我通过Visual Studio中的SQL Server数据库项目发布数据库时,我可以看到在数据库中创建的所有函数。当我查看发布脚本时,我可以看到数据库项目使用程序集的二进制。这意味着,它执行类似

的操作
CREATE ASSEMBLY SQLCLRTest
AUTHORIZATION [dbo]
FROM 0x4D5A90000300000004000000FFFF000.......
WITH PERMISSION_SET = UNSAFE;

所以我的问题是为什么程序集通过DLL二进制文件正确注册,但是当我使用DLL的路径时却没有?

对此的任何帮助将不胜感激。

数据库服务器:SQL Server 2012.数据库项目在Visual Studio 2013中创建.CLR程序集在Visual Studio 2013中创建为单独的类库项目。

2 个答案:

答案 0 :(得分:2)

Visual Studio的发布步骤还包括一个单独的脚本,用于创建SQLCLR程序集中嵌入的函数和过程。因此,Visual Studio正在为您完成这两项工作。

执行CREATE ASSEMBLY脚本创建函数或过程。它只是将组件暴露给SQLCLR。在以这种方式创建装配时,必须手动/单独创建它们。

答案 1 :(得分:2)

  

为什么程序集通过DLL二进制文件正确注册,但是当我使用DLL的路径时却没有?

问题不在于装配的创建(您所指的是注册)。如果在运行-shared时没有收到错误,那么它确实已成功创建。

但是,程序集本身仅包含可以引用T-SQL包装器对象的.NET方法,但是创建程序集不会自动创建这些T-SQL包装器对象。那些需要明确创建。

SSDT使用的主要发布脚本是diff / incremental脚本,用于将目标数据库升级到项目隐含的状态。如果您想要始终获取CREATE语句而不管部署的任何更改,请务必:

  1. 绝对检查项目属性的“SQLCLR”选项卡上的“生成DDL”选项。此选项控制是否生成包装器对象CREATE语句(即CREATE ASSEMBLYCREATE PROCEDURECREATE FUNCTIONCREATE TYPECREATE AGGREGATE语句。 / p>

  2. (可选)选中“项目属性”的“项目设置”选项卡上的“创建脚本(.sql文件)”复选框。选中此选项后,每次进行构建时都会有 {Build tab.BuildOutputPath} \ {Build tab.BuildOutputFileName} _Create.sql 脚本。 _Create.sql 脚本将始终包含CREATE TRIGGER语句。

  3. 进行构建时,总会有 obj \ Debug \ {SQLCLR tab.AssemblyName} .generated.sql 脚本。该脚本将始终包含CREATE ASSEMBLY语句。如果您选中了“生成DDL”选项,该脚本还将包含CREATE ASSEMBLYCREATE PROCEDURECREATE FUNCTIONCREATE TYPECREATE AGGREGATE语句(#1以上)。此脚本不是完全可运行的,因为它不按顺序排列,但此脚本中的语句用于生成发布和可选的创建脚本。

    如果您选中了“创建脚本”选项(上面的#2),那么,假设您还选中了“生成DDL”选项(再次#1),CREATE TRIGGER,{{1} },CREATE PROCEDURECREATE FUNCTIONCREATE TYPE语句也将位于 {Build tab.BuildOutputPath} \ {Build tab.BuildOutputFileName} _Create.sql 脚本中。在此脚本中,语句的顺序正确。