Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Сбой развертывания проекта SQL CLR при создании сборки в базе данных

Автор вопроса: DarthVeganОтветов: 1

У меня есть папка с 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: я изменил базу данных на заслуживающую доверия, а затем выполнил эту команду, и я получаю ту же ошибку:

Создайте сборку DataSetExtensions из 'c:\ooplesclr\System.Data.DataSetExtensions.dll' с Permission_set = UNSAFE GO

ОБНОВЛЕНИЕ 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

Произошла ошибка .NET Framework во время выполнения определяемой пользователем подпрограммы или агрегата "CalculateInfo": 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()

Как исправить это исключение?

  • Вопрос не по порядку? Я предполагаю, что ошибка, отмеченная в первом абзаце, что вы получили после того, как вы скопировали эту DLL в папку с вашей DLL SQLCLR во втором абзаце, верно? И на какой версии SQL Server это будет развернуто? Solomon Rutzky 02.02.2015
  • @srutzky Да, я до сих пор не замечал, что вопрос вышел из строя. Но да, ты прав DarthVegan 02.02.2015

sqlsql-serversqlclr

Ответы

Ответ 1 · рейтинг 4 · Solomon Rutzky

Во-первых, "поддерживается" только небольшой список библиотек .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.

Возможно, вам лучше загрузить System.Data.DataSetExtensions отдельно в отдельный CREATE ASSEMBLY, указывающий на соответствующую папку C:\Windows\Microsoft.NET\Framework (или Framework64). . Особенно, если вы заметили, что в сообщении об ошибке указано "Размер кода равен нулю", что я видел только при попытке загрузить DLL из одной из папок Reference Assemblies.

Теперь, поскольку это неподдерживаемая библиотека, она, вероятно, делает вещи, которые не позволяют загружать ее как SAFE. Поскольку у нас нет информации о закрытом ключе, чтобы пойти по идеальному пути создания асимметричного ключа, а затем входа в систему на основе этого асимметричного ключа, у вас нет другого выбора, кроме как:

  • установите базу данных, которую вы развертываете, как НАДЕЖНУЮ через:

    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: Stairway to SQLCLR (требуется бесплатная регистрация).

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы