带有Out参数的SQL Server CLR UDF - 可能吗?

时间:2012-09-26 21:09:50

标签: c# sql-server clr user-defined-functions sqlclr

有没有办法为SQL Server创建一个CLR用户定义函数,它返回多个值而不使用表值函数语法?例如,假设我想执行坐标转换,例如:

[SqlFunction()]
public void ConvertCoordinates(SqlDouble x, SqlDouble y, SqlDouble z, out SqlDouble r, out SqlDouble t, out SqlDouble p)
{
   r = new SqlDouble(Math.Sqrt((x.Value*x.Value)+(y.Value*y.Value)+(z.Value*z.Value)));
   t = new SqlDouble(Math.Acos(r.Value / z.Value));
   p = new SqlDouble(Math.Atan(y.Value / x.Value));
}

这甚至可能吗?在这种情况下,表值函数似乎不合适,因为计算永远不会产生多个输出行。使用标量值函数语法,我将不得不编写三个不同的函数来执行计算并分别调用它们。鉴于我的实际用例,这是非常不切实际的。

我意识到上述逻辑可以使用纯T-SQL完成;我的实际用例更复杂,但仍然只会导致单行具有多个相互依赖的输出值。

所以,底线,是否可行?我不认为是,但人们可以希望。如果它是可行的,那么T-SQL看起来会调用这样一个函数吗?

3 个答案:

答案 0 :(得分:3)

由于您已经采用了CLR,您可以创建自己的CLR类型,您可以使用它来执行各种疯狂的操作。作为一个实际示例,本机空间类型以这种方式实现,HierarchyID也是如此。一旦定义了自己的类型,就可以让函数返回它。如果获得单个组件(如果我可以假设你的半径,theta和phi),请在返回的类型上创建方法。

答案 1 :(得分:1)

这是一个较老的问题,我在寻找一个非常相似的问题的答案时找到了它。

SQL函数允许返回值,但不允许使用输出参数。

SQL过程允许输出参数(但不是返回值)

我在MSDN示例中找到了这个:

http://technet.microsoft.com/en-us/library/ms131092.aspx

 [Microsoft.SqlServer.Server.SqlProcedure]
 public static void PriceSum(out SqlInt32 value)
 { … }

CREATE PROCEDURE PriceSum (@sum int OUTPUT)
AS EXTERNAL NAME TestStoredProc.StoredProcedures.PriceSum

当我从尝试注册函数切换到过程时,一切都解决了。应该指出的是,Function可以有一个返回值但是Stored Procedure不能。在我的情况下,我返回一个字符串值,并输出params以获取一些可选的详细信息,如状态代码等。我所做的只是将我的方法更改为void并将字符串值作为输出参数传回。

您的方法无论如何都是无效的,并且没有返回值,因此是使用存储过程而不是函数的完美候选。

答案 2 :(得分:-1)

我承认我没有尝试过,但我想T-SQL会想,

DECLARE @X FLOAT(53),
        @Y FLOAT(53),
        @Z FLOAT(53),
        @R FLOAT(53),
        @T FLOAT(53),
        @P FLOAT(53)

EXEC    ConvertCoordinates
        @X = 0,
        @Y = 0,
        @Z = 0,
        @R = @R OUTPUT,
        @T = @T OUTPUT
        @P = @P OUTPUT