有没有办法为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看起来会调用这样一个函数吗?
答案 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