首页 > 解决方案 > 使用 ref 参数从 dll 程序集创建 MS SQL Server 函数

问题描述

我想从已成功注册到 MS SQL Server 数据库中的 C# 库中创建一个函数作为程序集。C# 中的函数签名如下所示:

public static double DensityD11162Relative(double observedDensity, 
                                           double observedTemperature, 
                                           double observedPressure, 
                                           ref int errorCode)

为了在 SQL Server 中使用此函数,我尝试按如下方式创建函数:

CREATE FUNCTION DensityD11162Relative(@observedDensity float, 
                                    @observedTemperature float,
                                    @observedPressure float,
                                    @errorCode int) 
    RETURNS float
    AS
    EXTERNAL NAME [Flowcal.ApiVcfLibrary].[Flowcal.ApiVcfLibrary.Customary.Original.Lubricants].DensityD11162Relative

但是,这会导致以下错误消息:

Msg 6580, Level 16, State 1, Procedure DensityD11162Relative, Line 3 [Batch Start Line 0]
Declarations do not match for parameter 4. .NET Framework reference and T-SQL OUTPUT parameter declarations must match.
Msg 6552, Level 16, State 3, Procedure DensityD11162Relative, Line 3 [Batch Start Line 0]
CREATE FUNCTION for "DensityD11162Relative" failed because T-SQL and CLR types for parameter "@errorCode" do not match.

该消息指出第四个参数的类型错误,这是有道理的,因为 C# 签名表明它需要一个ref int参数。 我的问题是:从程序集创建 SQL 函数时,我可以传递 ref 参数(或占位符)吗?如果是这样,怎么做?如果没有,是否有任何方法可以在不使用 C# 编写包装器的情况下解决这个问题?

我正在使用 SQL Server 2017

标签: c#sqlsql-serverclrsql-function

解决方案


由于您似乎可以控制 DLL 和函数,因此您可以删除 ErrorCode 的 ref 参数,并从您的方法中返回一个字符串,其中包含以下内容:

double|errorCode 

然后在 SQL 中,您可以拆分字符串结果并将其转换为客户端上的浮点数和整数。

(我知道有一种更有效的方法来写这个,每一步都更清楚)

Declare @StringResult nvarchar(50)
Declare @Result float
Declare @Delimiter nvarchar(1)
Declare @SeperateIndex int
Declare @ErrorCode int

Set @Delimiter = '|'

-- Example return value
Set @StringResult = '50|-1100'

Set @SeperateIndex = CharIndex(@Delimiter,@StringResult)

Set @Result = Convert(float,Substring(@StringResult,0,@SeperateIndex))
Set @ErrorCode = Convert(int, Substring(@StringResult, @SeperateIndex + 1, 
Len(@StringResult) - @SeperateIndex + 1))

Select @Result, @ErrorCode

在此示例中,结果如下所示:

50  -1100

只是一个想法。


推荐阅读