Я перенес свои локальные базы данных SQL Server 2008 R2 в управляемый экземпляр Azure SQL Server (SQL Server 2017).Одна база данных является архивной (только для чтения), одна - базой данных OLTP, а третья - служебной базой данных, в которой хранятся общие функции, хранимые процедуры и сценарии обслуживания.Все прошло очень гладко для всех трех БД, за исключением сборки CLR в служебной БД.Сборка обеспечивает функциональность Regex в коде TSQL - очень полезно!Я основал это на коде Фила Фактора здесь .Первоначально он был загружен в локальную БД из скомпилированной DLL.Это работает как чемпион там.Но в SQL MI я получаю следующую ошибку при запуске SP, который использует одну из функций CLR:
Сообщение 10314, уровень 16, состояние 11, процедура dbo.globalSearch, строка 22 [Пакетный запускСтрока 2]
Произошла ошибка в Microsoft .NET Framework при попытке загрузить идентификатор сборки 65541. Возможно, на сервере не хватает ресурсов или сборка не является доверенной.Запустите запрос еще раз или просмотрите документацию, чтобы узнать, как решить проблемы доверия к сборке.Дополнительные сведения об этой ошибке:
System.IO.FileLoadException: не удалось загрузить файл или сборку 'regexsqlclr, версия = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null' или одну из ее зависимостей.Произошла ошибка, связанная с безопасностью.(Исключение из HRESULT: 0x8013150A)
System.IO.FileLoadException:
в System.Reflection.RuntimeAssembly._nLoad (AssemblyName fileName, расположение строки кода, свидетельство AssemblySecurity, местоположение RuntimeAssemblyHint, StackCrawlMarkleotFoundPhieldParkPhieldParkPhieldPackPackPackPhieldPackPackPackPackforIntrospection, булевы suppressSecurityChecks)
на System.Reflection.RuntimeAssembly.InternalLoadAssemblyName (AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark & stackMark, IntPtr pPrivHostBinder, булевой throwOnFileNotFound, Boolean, Boolean forIntrospection suppressSecurityChecks)
в System.Reflection.RuntimeAssembly.InternalLoad (String assemblyString, Evolution AssemblySecurity, StackCrawlMark & stackMark, IntPtr pPrivHostBinder, логическое значение forIntrospection)
в System.Reflection.RuntimeAssembly.InternalLoad (строковая строка AssemblyString, Evidence Assembly_Security, BoostanSpectionMell для StormMellMarSMM)em.Reflection.Assembly.Load (String assemblyString)
Я попытался решить проблемы доверия к сборке, используя шаги в этом сообщении MSDN, в частности, выполняя
sys.sp_add_trusted_assembly
, который преуспевает, но ничего не меняет.Тогда я подумал, что, поскольку он предполагает, что он не может загрузить файл, который кажется разумным, поскольку файл не существует в SQL MI, где у меня нет доступа к файловой системе, я должен попытаться удалитьи воссоздание с varbinary
.Я только сказал, что , кажется, имеет смысл, потому что файл также не существует ни на одном из моих других локальных серверов, кроме того, с которого я первоначально загрузил его, и он прекрасно работает на всех них.Но я готов попробовать что угодно!Поэтому, используя SSMS, я записал ассемблер в виде DROP
и CREATE
, который использует синтаксис FROM BINARY
, а также выполнил сценарий для всех функций.CREATE ASSEMBLY
успешно, так что я думаю, что я на правильном пути.Затем я пытаюсь создать первую функцию и BAM, еще одна ошибка!На этот раз ошибка читает
Msg 6505, уровень 16, состояние 2, процедура RegexIndex, строка 2
Не удалось найти тип 'RegexSQLCLR.RegularExpressionFunctions' в сборке 'RegexFunctions'.
Я часами гуглял, пытаясь найти решение этой проблемы, и мне не повезло.Хотя этот синтаксис для части класса в предложении EXTERNAL NAME
отлично работает для сборки, загруженной из файла.Я убедился, что сценарий varbinary
, создаваемый SSMS, идентичен двоичному файлу исходной библиотеки DLL.Кто-то на форуме Microsoft предложил мне убедиться, что DLL была скомпилирована с опцией Any CPU
- так и было.В качестве проверки работоспособности я проделал ту же процедуру на одном из локальных серверов, то есть DROP
и CREATE ASSEMBLY FROM BINARY
, и получил точно такой же результат: я не могу загрузить ни одну из функций CLR!Я перепробовал все мыслимые изменения имен классов, которые я могу придумать, но безрезультатно.Вот код для CREATE ASSEMBLY
и CREATE FUNCTION
CREATE ASSEMBLY [RegexFunction]
AUTHORIZATION [dbo]
FROM 0x4D5A90000 *truncated_for_brevity*
WITH PERMISSION_SET = SAFE
CREATE FUNCTION RegExIndex
(
@Pattern NVARCHAR(4000),
@Input NVARCHAR(MAX),
@Options int
)
RETURNS int
AS EXTERNAL NAME
RegexFunction.[RegexSQLCLR.RegularExpressionFunctions].RegExIndex
GO
RegexSQLCLR
- это имя исходной DLL, а RegularExpressionFunctions
- имя класса.RegexSQLCLR
также является именем, указанным в столбце name
sys.assembly_files
после использования CREATE ASSEMBLY FROM BINARY
;в противном случае полный путь к исходной DLL находится в столбце name
.