在数据库上创建程序集时,部署SQL CLR项目失败

我在服务器上的文件夹中有一个包含3个dll文件的文件夹,用于创建程序集。 我首先尝试了以下代码并得到一个错误,说它无法在服务器上找到system.data.datasetextensions.dll文件,我将dll从我的计算机复制并粘贴到我的clr项目所在的同一文件夹中并尝试再次运行该命令。

Create Assembly OoplesCLR from 'c:\ooplesclr\OoplesFinanceCLR.dll' with Permission_set = SAFE GO 

将dll从我的计算机复制到服务器文件夹后,我现在收到此错误

 Warning: The Microsoft .NET Framework assembly 'system.data.datasetextensions, version=4.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089.' you are registering is not fully tested in the SQL Server hosted environment and is not supported. In the future, if you upgrade or service this assembly or the .NET Framework, your CLR integration routine may stop working. Please refer SQL Server Books Online for more details. Msg 6218, Level 16, State 2, Line 1 CREATE ASSEMBLY for assembly 'OoplesFinanceCLR' failed because assembly 'System.Data.DataSetExtensions' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database. CLR Verifier error messages if any will follow this message [ : System.Data.DataRowComparer::get_Default][mdToken=0x6000001][offset 0x00000000] Code size is zero. [ : System.Data.DataRowComparer`1[TRow]::Equals][mdToken=0x6000004][offset 0x00000000] Code size is zero. [ : System.Data.DataRowComparer`1[TRow]::GetHashCode][mdToken=0x6000005][offset 0x00000000] Code size is zero. [ : System.Data.DataRowComparer`1[TRow]::.cctor][mdToken=0x6000006][offset 0x00000000] Code size is zero. [ : System.Data.DataRowComparer`1[TRow]::.ctor][mdToken=0x6000002][offset 0x00000000] Code size is zero. [ : System.Data.DataRowComparer`1[TRow]::get_Default][mdToken=0x6000003][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::CopyToDataTable[T]][mdToken=0x6000008][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::CopyToDataTable[T]][mdToken=0x6000009][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::CopyToDataTable[T]][mdToken=0x600000a][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::AsDataView[T]][mdToken=0x600000c][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::AsEnumerable][mdToken=0x6000007][offset 0x00000000] Code size is zero. [ : System.Data.DataTableExtensions::AsDataView][mdToken=0x600000b][offset 0x00000000] Code size is zero. [ : System.Data.EnumerableRowCollection::System.Collections.IEnumerable.GetEnumerator][mdToken=0x600000e][offset 0x00000000] Code size is zero. [ : System.Data.EnumerableRowCollection::.ctor][mdToken=0x600000d][offset 0x00000000] Code size is zero. [ : System.Data.EnumerableRowCollection`1[TRow]::System.Collections.IEnumerable.GetEnumerator][mdToken=0x600000f][offset 0x00000000] Code size is zero. 

我做错了什么,如何解决这个问题?

更新1:我将数据库更改为可信,然后运行此命令,我收到相同的错误:

使用Permission_set = UNSAFE GO从’c:\ ooplesclr \ System.Data.DataSetExtensions.dll’创建程序集DataSetExtensions

更新2:尝试在同一数据库上创建一个函数来运行程序集。 我的用户定义函数是这样的:

 public partial class UserDefinedFunctions { [SqlFunction] public static SqlString CalculateInfo() { // first get data from the tables and then process the data getData(); // Put your code here return new SqlString ("test"); } 

更新3:我使用以下代码创建了没有任何警告或错误的函数,但我无法运行它,因为它表示不存在这样的存储过程…

 GO CREATE FUNCTION [dbo].[CalculateInfo] ( ) RETURNS NVARCHAR (MAX) AS EXTERNAL NAME [OoplesCLR].[UserDefinedFunctions].[CalculateInfo] 

更新4:即使它说不存在这样的存储过程,我设法运行它,我收到以下错误:

 Msg 6522, Level 16, State 1, Line 4 

在执行用户定义的例程或聚合“CalculateInfo”期间发生.NET Framework错误:System.Security.HostProtectionException:尝试执行CLR主机禁止的操作。

 The protected resources (only available with full trust) were: All The demanded resources were: Synchronization, ExternalThreading System.Security.HostProtectionException: at UserDefinedFunctions.getData() at UserDefinedFunctions.CalculateInfo() 

如何修复此exception?

首先,“支持”只有一小部分.NET Framework库。 您可以在MSDN页面上找到支持的.NET Framework库的列表 。 System.Data.DataSetExtensions不是其中之一。 这就是你得到第一个错误的原因。

发布的第二件事是警告,而不是错误。 它告诉您,当您正在执行不受支持的操作时,您可能会遇到Microsoft不关心或修复的一个或多个问题。

在要部署程序集的数据库中运行以下命令:

 SELECT * FROM sys.assemblies sa WHERE sa.is_user_defined = 1; 

你应该看到两者。 虽然如果System.Data.DataSetExtensions具有依赖库,它们将不会被自动加载,因为只有初始CREATE ASSEMBLY指向的文件夹才会被加载,现在是你构建DLL而不是.NET Framework的地方夹。

您可能最好在自己的CREATE ASSEMBLY加载System.Data.DataSetExtensions ,指向相应的C:\ Windows \ Microsoft.NET \ Framework(或Framework64)文件夹。 特别是如果您注意到错误消息显示“代码大小为零”,这是我在尝试从其中一个参考程序集文件夹加载DLL时看到的。

现在,因为这是一个不受支持的库,它可能会做一些不允许它作为SAFE加载的东西。 由于我们没有私钥信息才能成为创建非对称密钥的理想路径,然后是基于该非对称密钥的登录,因此您别无选择,只能:

  • 通过以下方式将您要部署的数据库设置为TRUSTWORTHY:

     ALTER DATABASE [DatabaseName] SET TRUSTWORTHY ON; 
  • WITH PERMISSION_SET = UNSAFE加载程序集

实质上:

 USE [DatabaseName]; ALTER DATABASE CURRENT SET TRUSTWORTHY ON; CREATE ASSEMBLY [System.Data.DataSetExtensions] FROM 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Data.DataSetExtensions.dll' WITH PERMISSION_SET = UNSAFE; 

之后你应该可以加载你的程序集,虽然它也可能必须设置为UNSAFE

我会删除您放在build文件夹中的System.Data.DataSetExtensions.dll副本。


有关SQLCLR的更多信息,请参阅我在SQL Server Central上编写的系列: SQLCLR的阶梯 (需要免费注册)。