Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Максим Чистяков
Member

Откуда:
Сообщений: 23
Всем привет! Знакомлюсь с созданием CLR функций. При добавлении в mssql сборки для сторонней библиотеки Newtonsoft.Json получаю вот такую ошибку
+
Msg 6218, Level 16, State 2, Line 10
CREATE ASSEMBLY for assembly 'ClassLibrary1' failed because assembly 'System.Runtime.Serialization' 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.Runtime.Serialization.SRDescriptionAttribute::get_Description][mdToken=0x6000002][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SRDescriptionAttribute::.ctor][mdToken=0x6000001][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SRCategoryAttribute::GetLocalizedString][mdToken=0x6000004][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SRCategoryAttribute::.ctor][mdToken=0x6000003][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::.cctor][mdToken=0x600000b][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::.ctor][mdToken=0x6000005][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::get_Resources][mdToken=0x6000006][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::GetString][mdToken=0x6000007][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::GetString][mdToken=0x6000008][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::GetString][mdToken=0x6000009][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.SR::GetObject][mdToken=0x600000a][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.DiagnosticUtility::.cctor][mdToken=0x6000015][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.DiagnosticUtility::get_DiagnosticTrace][mdToken=0x600000c] Сбой загрузки типа.
[ : System.Runtime.Serialization.DiagnosticUtility::get_ExceptionUtility][mdToken=0x600000d][смещение 0x00000000] Нулевой размер кода.
[ : System.Runtime.Serialization.DiagnosticUtility::InitDiagnosticTraceImpl][mdTo...


Изначальная постановка задачи: нужно протестировать парсинг JSON на старой версии сиквела, которая ещё не имеет встроенной поддержки JSON (поэтому я не использую встроенные средства 2017 скуля). Для получения value по key, решил использовать CLR функцию, и из всех примеров, что я нашёл, заработал пример с библиотекой Newtonsoft.Json.
1. Создал простой парсер для JSON. Для работы с JSON добавил через нугет стороннюю библиотеку Newtonsoft.Json www.newtonsoft.com. В качестве консольного приложения работает замечательно и выдаёт ожидаемый результат. Создал новый проект типа библиотека dll, перенёс туда весь код, компилируется-билдится хорошо. Сам код:
+
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
//using System.Runtime.Serialization;
//using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Data.SqlClient;
 
namespace ClassLibrary1
 
{
    public class Program
    {
    [SqlFunction(DataAccess = DataAccessKind.Read)]
        public static int getValue1 () { return 1; }
 
        public static decimal getDecimalValue(String js, String accessTocken)
        {
            try
            {
                JObject o = JObject.Parse(js);
                return (decimal)o[accessTocken];
            }
            catch (JsonReaderException)
            {
                return -1;
            }
        }
 
        public static String getStringlValue(String js, String accessTocken)
        {
            try
            {
                JObject o = JObject.Parse(js);
                return (String)o[accessTocken];
            }
            catch (JsonReaderException)
            {
                return "No such JSON key";
            }
        }
 
        public static void Main(String[] args)
        {
            String js = @"{ ""DailyPercentRate"":0.505,""PenaltiesPercentRate"":20,""PenaltiesStartDay"":1,""RestPercentOfBody"":0,""SecondPeriodPenaltiesPercentRate"":0.2,""SecondPeriodPenaltiesStartDay"":100}";
            //Console.WriteLine(dailyPercentRate);
            Console.WriteLine(getDecimalValue(js, "DailyPercentRate"));
        }
    }
}


2. При попытке CREATE ASSEMBLY для ClassLibrary1.dll, получаю ошибку Assembly 'Newtonsoft.Json' references assembly 'system.runtime.serialization, which is not present in the current database. SQL Server attempted to locate and automatically load the referenced assembly from the same location where referring assembly came from, but that operation has failed . Please load the referenced assembly into the current database and retry your request
3. Закомментировал в классе все методы, кроме getValue1. Скомпилировал, сбилдил – функция вида
create function dbo.clr_test() returns int as
external name ClassLibrary1.[ClassLibrary1.Program].getValue1;
создаётся и работает. Таким образом, понятно что проблема в Newtonsoft.Json.dll.
4. Решил в сивеле создать отдельно assembly Newtonsoft.Json.dll. При попытке CREATE ASSEMBLY получаю ошибку, о которой писал ранее - assembly 'system.runtime.serialization, which is not present in the current.
4. Добавил в C# проекте в референсы System.Runtime.Serialization. Выставил в свойствах C# проекта “Copy local = true”, чтобы этот файл всегда появлялся в папке \bin рядом с нужной мне библиотекой. С ошибкой выше разобрался, но похожим образом CREATE ASSEMBLY ругался на отсутствие:
- System.ServiceModel.Internals.dll
- System.Runtime.DurableInstancing.dll
- SMDiagnostics.dll
Их в NuGet’ах не найти, поэтому решил проблему тем, что копировал из директории "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\{название_сборки}\v4.0_4.0.0.0__b77a5c561934e089" в директорию проекта с бинарниками.
Свойства проекта на C# пробовал версии .NET Framework 4.0 и .NET Framework 4.0 Client Profile (сейчас указана 4.0 Client Profile). В справке библиотеки [url=]https://www.nuget.org/packages/Newtonsoft.Json/12.0.1[/url] указано, что для .NET Framework 4.0 дополнительных зависимостей нет.
Разработку веду в Visual Studio 2017.
Mssql - Microsoft SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64) Developer Edition (64-bit) on Windows 10 Enterprise LTSC 2019 10.0 <X64> (Build 17763: ).
5. Получившийся результат: плюётся ошибками уже не моментально, а думает несколько секунд, и выдаёт то, что я описал вначале ( 'System.Runtime.Serialization' 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.Runtime.Serialization.SRDescriptionAttribute::get_Description][mdToken=0x6000002][смещение 0x00000000] Нулевой размер кода
, и т.д.)

6. Как видно, он ругается на верификацию, но я добавил сборку в список доверенных через sp_add_trusted_assembly. Он появился в sys.trusted_assemblies. Также добавил System.ServiceModel.Internals.dll,System.Runtime.DurableInstancing.dll, SMDiagnostics.dll.
Добавил в sql сборки System.ServiceModel.Internals и SMDiagnostics. Сборки System.Runtime.Serialization и System.Runtime.DurableInstancing добавить не могу, в обоих ругается на System.Runtime.Serialization.
Судя по ошибке Msg 6218, проблема в разных версиях .NET Framework, но как я писал в п.4, версии проекта и системы совпадают.
7. В качестве последней меры, добавил сборку newtonsoft в GAC
Developercomand Prompt for VS —> 
gacutil -i {path_to_dll}\Newtonsoft.Json.dll —> 
Корпорация Майкрософт (Microsoft Corporation)
Сборка успешно добавлена в кэш
, но не спасло.

Прошу помочь разобраться. Отвечать буду, скорее всего, с задержкой полчаса/час, заранее спасибо за ответы.
5 дек 19, 15:55    [22033306]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7399
Максим Чистяков,

надо задеплоить на сервер system.runtime.serialization. Сам сервер поддерживает только trusted системные сборки, их перечень есть в хелпе. Все остальные надо публиковать, что порождает проблему - при апгрейде .Net вам придется перепубликовывать и обновленные сборки, иначе получите ошибку, что, мол, таких версий нет в GAC.

Сообщение было отредактировано: 5 дек 19, 16:40
5 дек 19, 16:37    [22033361]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7399
Мой совет - забейте и сделайте отдельный сервер приложений. Мы с этим который год мучаемся. Плюс никакой мобильности сервера, приходится открывать доступы с него а это кластер. В общем, расходу на эксплуатацию портят все удовольствие от простоты разработки.
5 дек 19, 16:43    [22033366]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1172
Максим Чистяков,

в общем случае вам не достает сборки System.Runtime.Serialization в БД.
но это сборка строго имени поэтому деплоить ее сервер позволит только из директории где она реально зарегистрирована.

к примеру для .NET 4.0
create assembly [System.Runtime.Serialization] from 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll' with permission_set = unsafe


если переложите ее в другой каталог и попытаетесь залить оттуда сервер будет ругаться на политику безопасности.

После того как задеплоите сборку сериализации, сможете залить json;
5 дек 19, 16:54    [22033375]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Максим Чистяков
Member

Откуда:
Сообщений: 23
felix_ff,

благодарю за ответ, ваш совет оказался правильным! Удивляюсь, почему мне самому это в голову не пришло и я три дня пытался подключить библиотеку из папки с бинарниками проекта, вместо того чтобы создать assembly из оригинальной директории "C:\Windows\Microsoft.NET\Framework64".
5 дек 19, 17:20    [22033403]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Максим Чистяков
Member

Откуда:
Сообщений: 23
Владислав Колосов,

а можете сказать, чего мучаетесь? Какие подводные камни с тем, чтобы создать сборку из своей библиотеки с применением сторонних решений?
5 дек 19, 17:22    [22033408]     Ответить | Цитировать Сообщить модератору
 Re: Error Msg 6218 при попытке добавления сторонней сборки в SQL Server 2017  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7399
Максим Чистяков,

сборки из проекта БД развертываются. Студия копирует в скрипт сборки в шестнадцатеричном виде в скрипт развертывания и публикует как CREATE ASSEMBLY FROM 0x4D5A90000300000004000000FFFF000 ... . В проекте базы надо создать ссылку на сборку, сборку поместить можно в любую папку.
5 дек 19, 17:29    [22033415]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить