Deploying SQL CLR Project fails when creating assembly on database

只愿长相守 提交于 2019-12-12 09:16:05

问题


I have a folder with 3 dll files in the folder on the server that I'm using to create the assembly. I tried the following code at first and got an error that said it couldn't find the system.data.datasetextensions.dll file on the server and I copied and pasted the dll from my computer to the same folder where my clr project was located and tried running the command again.

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

I'm now getting this error after copying the dll from my computer to the server folder

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.

What am I doing wrong and how can I fix this?

UPDATE 1: I changed the database to trustworthy and then ran this command and I'm getting the same error:

Create Assembly DataSetExtensions from 'c:\ooplesclr\System.Data.DataSetExtensions.dll' with Permission_set = UNSAFE GO

UPDATE 2: Trying to create a function on the same database to run the assembly. My user defined function is this:

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");
}

UPDATE 3: I created the function without any warnings or errors with the following code but I can't run it because it says that no such stored procedure exists...

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

UPDATE 4: Even though it is saying no such stored procedure exists, I managed to run it and I'm getting the following error:

Msg 6522, Level 16, State 1, Line 4

A .NET Framework error occurred during execution of user-defined routine or aggregate "CalculateInfo": System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host.

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()

How do I fix this exception?


回答1:


First off, only a short list of .NET Framework libraries are "supported". You can find that list on the MSDN page for Supported .NET Framework Libraries. System.Data.DataSetExtensions is not one of them. That is why you got the first error.

The second thing posted is a warning, not an error. It is telling you that you can run into one or more problems that Microsoft will not care about or fix as you are doing something that is unsupported.

Run the following in the database where you are deploying the assemblies:

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

and you should see both. Although if System.Data.DataSetExtensions has dependent libraries, they won't be automatically loaded because only the folder that the initial CREATE ASSEMBLY is pointing to will get loaded, and that is now where your DLL is being built and not the .NET Framework folder.

You might be better off loading System.Data.DataSetExtensions by itself in its own CREATE ASSEMBLY pointing to the appropriate C:\Windows\Microsoft.NET\Framework (or Framework64) folder. Especially if you notice that the error message shows "Code size is zero", which I have only seen when trying to load the DLL from one of the Reference Assemblies folders.

Now, because this is an unsupported library it probably does stuff that disallow it from being loaded as SAFE. Since we don't have the private key info in order to go the ideal route of creating an Asymmetric Key and then a Login based on that Asymmetric Key, you have little choice but to:

  • set the database you are deploying to as TRUSTWORTHY via:

    ALTER DATABASE [DatabaseName] SET TRUSTWORTHY ON;
    
  • load the assembly WITH PERMISSION_SET = UNSAFE

Essentially:

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;

After that you should be able to load your assembly, though it will likely have to be set to UNSAFE as well.

And I would delete the copy of System.Data.DataSetExtensions.dll that you put in your build folder.


For more info on SQLCLR in general, please see the series I am writing on SQL Server Central: Stairway to SQLCLR (free registration required).



来源:https://stackoverflow.com/questions/28268373/deploying-sql-clr-project-fails-when-creating-assembly-on-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!