使 SQL 2016 年的程序集在 SQL 2017 年工作(例如:从 SQL Server 2017 调用数学解析器)

Make assembly from SQL 2016 work in SQL 2017 (ex: Calling Math Parser from SQL Server 2017)

我有一个存储过程需要一些复杂的数学表达式求值。 有一个公式,这个存储过程计算它的值。

它调用定义如下的 UDF:

ALTER FUNCTION [dbo].[udfComputeMath]
    (@inputString [NVARCHAR](MAX))
RETURNS [NVARCHAR](4000) 
WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [SMP_Assembly].[SuperMathParser.MathParser].[ComputeMath] 

这是相当古老的代码,从 SQL Server 2008 R2(至少)到 2016 年,它都运行良好。

但是现在我们尝试将我们的数据库更新到 SQL Server 2017,但这不再有效。

我收到以下错误:

Msg 10314, Level 16, State 11, Procedure GetPermitTypeFeesByPermitID, Line 88 [Batch Start Line 0]
An error occurred in the Microsoft .NET Framework while trying to load assembly id 65536. The server may be running out of resources, or the assembly may not be trusted. Run the query again, or check documentation to see how to solve the assembly trust issues. For more information about this error:

System.IO.FileLoadException: Could not load file or assembly 'supermathparser, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A) System.IO.FileLoadException:

at 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 assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)

at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)

at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) at System.Reflection.Assembly.Load(String assemblyString)

知道如何在 SQL Server 2017 中再次使用它吗?

谢谢

我的假设是您尝试调用它的数据库刚刚恢复到 SQL Server 2017 数据库,对吗?如果是这样,您尝试调用的函数要么是您自己(公司)开发的,要么是第三方程序集 - 它不是内置的 MS 程序集(程序集 ID - 65536 - 也表明了这一点)。

我的猜测是 digital.aaron 在他的评论中指出的问题,它与 SQL Server 2017 中更改的 CLR 安全模型有关。您可以在this blogpost, and here easily:ish 修复它的方法。

希望对您有所帮助!

尼尔斯

Link 到 "easily fix" 不起作用,更多上下文会更有帮助。我最终快速而肮脏地进行了以下操作(运行 on master):

ALTER DATABASE <DatabaseName> SET trustworthy ON

此处链接的博客 post 仍然有效并且信息量很大