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

Создайте сборку 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()

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


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


Ответы (1)


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

person Solomon Rutzky    schedule 01.02.2015
comment
Я выполнил этот запрос и ничего не вижу - person DarthVegan; 02.02.2015
comment
Я обновил свой вопрос, чтобы показать внесенные изменения, и я все еще получаю ту же ошибку. - person DarthVegan; 02.02.2015
comment
@user3610374 user3610374 Я только что обновил, чтобы упомянуть об этой проблеме. Размер кода равен нулю, я считаю, что это происходит только при попытке загрузить эталонную сборку, а не настоящую сборку. - person Solomon Rutzky; 02.02.2015
comment
Мой последний вопрос: как мне запустить свою функцию в базе данных? Я читаю статью, в которой говорится о создании функции для сборки, но не приводится пример. - person DarthVegan; 02.02.2015
comment
Наконец-то я смог создать сборку. Теперь я просто пытаюсь понять, как создать функцию в базе данных, чтобы иметь возможность запускать код - person DarthVegan; 02.02.2015
comment
Вы используете проект базы данных SSDT? Если вы делаете публикацию, она должна создать для вас функцию. - person Solomon Rutzky; 02.02.2015
comment
Я не думаю, что это проект базы данных SSDT. Я создал проект пользовательской функции SQL CLR С#. - person DarthVegan; 02.02.2015
comment
@user3610374 user3610374 Что-то нужно будет вызвать CREATE FUNCTION и сослаться на метод в DLL. В свойствах вашего проекта у вас есть вкладка для SQLCLR? - person Solomon Rutzky; 02.02.2015
comment
Да, у меня есть вкладка для SQLCLR - person DarthVegan; 02.02.2015
comment
Хорошо, я считаю, что успешно создал функцию. Я отправил команду, которую пробовал выше, и у меня не было ошибок или предупреждений, но она не позволит мне запустить функцию, потому что говорит, что такой хранимой процедуры не существует. Я могу подтвердить, что вижу функцию в базе данных в разделе программируемость › скалярные функции. Мне удалось запустить функцию, и я получаю сообщение об ошибке, которое я вставил выше в деталях моего вопроса. - person DarthVegan; 02.02.2015
comment
@user3610374 user3610374 Не уверен, что вы подразумеваете под хранимой процедурой, когда создаете функцию. И это последнее сообщение об ошибке означает, что ваша сборка должна быть установлена ​​на UNSAFE. Я бы также посоветовал вам провести МНОГО тестов и с несколькими пользователями, поскольку вполне вероятно, что вы не принимаете во внимание общий характер среды SQLCLR, особенно при использовании таких функций, как синхронизация и ExternalThreading. Я также поставлю ссылку в своем ответе на серию статей, которые я пишу о SQLCLR. - person Solomon Rutzky; 02.02.2015
comment
@user3610374 user3610374 нет, если он сейчас работает. Но если вы добавили как SAFE, просто используйте ALTER ASSEMBLY. - person Solomon Rutzky; 02.02.2015