Sql server 具有任意参数列表的用户定义函数
Coalesce()内置函数接受任意数量的参数 在SQL Server 2012中,是否可以使用相同的语法编写一个用户定义的函数来执行此操作?我不想使用表变量或逗号分隔的列表 我想实现一个Coalesce()函数,它返回传入的最低非空元素,而不是传入的第一个非空元素。这是为了满足新的用户需求。Coalesce()不需要创建表变量,而且,由于我正在用新逻辑替换现有的Coalesce()调用,因此我希望编写新函数,使其以相同的方式运行,包括接受任意数量的元素Sql server 具有任意参数列表的用户定义函数,sql-server,tsql,sql-server-2012,parameter-passing,user-defined-functions,Sql Server,Tsql,Sql Server 2012,Parameter Passing,User Defined Functions,Coalesce()内置函数接受任意数量的参数 在SQL Server 2012中,是否可以使用相同的语法编写一个用户定义的函数来执行此操作?我不想使用表变量或逗号分隔的列表 我想实现一个Coalesce()函数,它返回传入的最低非空元素,而不是传入的第一个非空元素。这是为了满足新的用户需求。Coalesce()不需要创建表变量,而且,由于我正在用新逻辑替换现有的Coalesce()调用,因此我希望编写新函数,使其以相同的方式运行,包括接受任意数量的元素 我知道我还可以采取其他方法——我想尽量减
我知道我还可以采取其他方法——我想尽量减少我必须进行的重写。是的,这是可能的。只是T-SQL中没有。您需要编写一个CLR函数 如果可以避免的话,我不想使用表变量或逗号分隔的列表 TVP是一条路要走。但如果不想定义表类型,可以使用老式的XML:
CREATE TABLE tab(id INT, a INT, b INT, c INT, d INT);
INSERT INTO tab(id,a,b,c,d) VALUES(1,1,NULL,NULL,NULL);
INSERT INTO tab(id,a,b,c,d) VALUES(2,2,2,NULL,NULL);
INSERT INTO tab(id,a,b,c,d) VALUES(3,3,3,3,NULL);
INSERT INTO tab(id,a,b,c,d) VALUES(4,4,4,4,4);
功能:
CREATE FUNCTION dbo.my_func(@input XML)
RETURNS INT
AS
BEGIN
RETURN
(
SELECT SUM(a.b.value('.', 'INT')) --any logic here, for simplicity's sake SUM
FROM @input.nodes('/*') AS sub(c)
CROSS APPLY sub.c.nodes('@*') a(b)
);
END;
并致电:
SELECT t1.*, sub.*, dbo.my_func(sub.x) AS result
FROM tab t1
CROSS APPLY (SELECT a,b,c,d
FROM (SELECT 1) t2(q) FOR XML AUTO) sub(x);
输出:
┌────┬───┬──────┬──────┬──────┬───────────────────────────────┬────────┐
│ id │ a │ b │ c │ d │ x │ result │
├────┼───┼──────┼──────┼──────┼───────────────────────────────┼────────┤
│ 1 │ 1 │ null │ null │ null │ <t2 a="1"/> │ 1 │
│ 2 │ 2 │ 2 │ null │ null │ <t2 a="2" b="2"/> │ 4 │
│ 3 │ 3 │ 3 │ 3 │ null │ <t2 a="3" b="3" c="3"/> │ 9 │
│ 4 │ 4 │ 4 │ 4 │ 4 │ <t2 a="4" b="4" c="4" d="4"/> │ 16 │
└────┴───┴──────┴──────┴──────┴───────────────────────────────┴────────┘
请注意,函数名是不同的。此外,您还需要使用能够满足大多数情况的数据类型,甚至是满足其预期用途的
sqlvariant
数据类型,特别是表变量参数。我不会使用逗号分隔的列表,因为您只需要在之后将其转换为表。但是表值参数是这里的最佳选择。然而,这可能是一个XY问题,您能告诉我们您试图实现什么吗?您可以创建一个带有可选参数和默认值的函数。(具有可选参数的SP示例为。)这与具有数量不可预测的sql\u variant
参数不同,但可能很有用。我已用其他详细信息更新了我的初始问题。您能否在我的案例中定义“最早日期”。但同样,这与问题的重点无关,即“可以像Coalesce()函数那样在SQL Server中编写一个接受任意数量参数的UDF吗?”这不是一个像Coalesce()那样接受任意数量参数的用户定义函数。@Brian不,在纯T-SQL中,你不能做你想做的事情。我回答了你的第二部分。正确的方法是TVP。不,您没有,因为传入XML字符串与Coalesce()函数的“语法”不同。虽然您的注释是正确的@Brian,但这是一种原生方法,不会更改服务器默认值,也不会引入像CLR这样庞大的内容,因为它不容易实现,也不会像可移植的那样。也许,@scsimon,但这并没有改变卢卡斯的回答不符合我需要的事实。我问“有可能做X吗?这就是我为什么要做X”,这个回答是一个冗长的“这是如何做Y,这是类似的,我认为你应该做的。”事实上,@ALollz,这正好回答了我的问题。
LOWEST2(a1, a2)
LOWEST3(a1, a2, a3)
LOWEST4(a1, a2, a3, a4)
...
LOWESTn(a1, a2, a3, a4, ..., an)