我已将我的本地 SQL Server 2008 R2 数据库迁移到 Azure SQL Server 托管实例 (SQL Server 2017)。一个数据库是存档(只读)数据库,一个是 OLTP 数据库,第三个是实用程序数据库,我在其中保存通用函数、存储过程和维护脚本。除了实用程序数据库中的 CLR 程序集外,所有三个数据库的一切都进行得非常顺利。该程序集在 TSQL 代码中提供正则表达式功能 - 非常有用!我基于此处的 Phil Factor 代码。最初,它是从已编译的 DLL 加载到本地数据库中的。它在那里像冠军一样工作。但在 SQL MI 上,运行使用 CLR 函数之一的 SP 时出现以下错误。
消息 10314,级别 16,状态 11,过程 dbo.globalSearch,第 22 行 [Batch Start Line 2]
Microsoft .NET Framework 在尝试加载程序集 id 65541 时发生错误。服务器可能资源不足,或者程序集可能不受信任。再次运行查询,或查看文档以了解如何解决程序集信任问题。有关此错误的更多信息:
System.IO.FileLoadException:无法加载文件或程序集“regexsqlclr,版本=0.0.0.0,文化=中性,PublicKeyToken=null”或其依赖项之一。发生与安全有关的错误。(来自 HRESULT 的异常:0x8013150A)
System.IO.FileLoadException:
在 System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark & stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblySecurityRef, Evidence assembly , RuntimeAssembly reqAssembly, StackCrawlMark & stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean for Introspection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark & stackMark, IntPtr pPrivHostBinder, Boolean for Introspection)
在 System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark & stackMark, Boolean forIntrospection)
在 System.Reflection.Assembly.Load(String assemblyString)
我尝试使用此MSDN 帖子中的步骤解决程序集信任问题,特别是执行
sys.sp_add_trusted_assembly
成功了,但什么也没改变。然后我想,既然它暗示它不能从文件加载,这似乎是有道理的,因为我无法访问文件系统的 SQL MI 中不存在该文件,我应该尝试从varbinary
. 我只是说这似乎是有道理的,因为除了我最初从中加载它的服务器之外,该文件也不存在于我的任何其他本地服务器上,并且它在所有服务器上都能完美运行。但是,我愿意尝试任何事情!因此,我使用 SSMS 将程序集编写为DROP
and CREATE
,它使用FROM BINARY
语法,并同样编写了所有函数的脚本。CREATE ASSEMBLY
成功了,所以我认为我在正确的轨道上。然后我尝试创建第一个函数和BAM,另一个错误!这次错误读取
消息 6505,级别 16,状态 2,过程 RegexIndex,第 2
行在程序集“RegexFunctions”中找不到类型“RegexSQLCLR.RegularExpressionFunctions”。
我已经在谷歌上搜索了几个小时,试图找到解决这个问题的方法,但运气却为零。尽管该EXTERNAL NAME
子句的类部分的语法对于从文件加载的程序集非常有效。我验证varbinary
了 SSMS 编写的脚本与原始 DLL 的二进制文件相同。Microsoft 论坛上的某个人建议我确保使用该Any CPU
选项编译 DLL - 确实如此。作为健全性检查,我在其中一台本地服务器上执行了相同的过程,即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
是原始 DLLRegularExpressionFunctions
的名称,是类的名称。RegexSQLCLR
也是after usingname
列中指定的名称;否则,原始 DLL 的完整路径在列中。sys.assembly_files
CREATE ASSEMBLY FROM BINARY
name