Создать серверную функцию MS SQL из сборки dll с параметром ref - PullRequest
0 голосов
/ 27 февраля 2020

Я хочу создать функцию из библиотеки C#, которую я успешно зарегистрировал в базе данных сервера MS SQL как сборка. Подпись функции в C# выглядит следующим образом:

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

Чтобы использовать эту функцию на SQL сервере, я попытался создать функцию следующим образом:

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. Мой вопрос: могу ли я передать аргумент ref (или заполнитель) при создании функции SQL из сборки? Если так, то как? Если нет, есть ли способ обойти это без написания оболочки в C#?

Я использую SQL Server 2017

1 Ответ

0 голосов
/ 27 февраля 2020

Поскольку у вас, похоже, есть контроль как над DLL, так и над функцией, вы можете удалить параметр ref для ErrorCode и просто вернуть строку из вашего метода, которая содержит что-то вроде:

double|errorCode 

Затем в SQL Вы можете разделить строковый результат и привести его к float и int на клиенте.

(я знаю, что есть более эффективный способ написания этого, более ясно разбивать каждый шаг)

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

Просто идея.

...