小编典典

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

sql

我用于创建程序集的服务器上的文件夹中有一个包含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()

如何解决此异常?


阅读 199

收藏
2021-04-22

共1个答案

小编典典

首先,仅“简短”支持.NET Framework库的简短列表。您可以在支持的.NET
Framework库
的MSDN页面上找到该列表。 System.Data.DataSetExtensions
不是其中之一。这就是为什么您遇到第一个错误的原因。

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

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

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

并且您应该看到两者。尽管如果 System.Data.DataSetExtensions 具有依赖的库,则不会自动加载它们,因为仅CREATE ASSEMBLY会加载最初指向的文件夹,并且现在正在构建DLL而不是.NET Framework文件夹。

您最好自行加载 System.Data.DataSetExtensions ,使其CREATE ASSEMBLY指向相应的 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为。

然后,我将删除您放入构建文件夹中的 System.Data.DataSetExtensions.dll 副本。


有关一般SQLCLR的详细信息,请参阅我在SQL Server
Central上撰写的系列文章:SQLCLR的阶梯(需要免费注册)。

2021-04-22