Sql server 具有任意参数列表的用户定义函数

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()调用,因此我希望编写新函数,使其以相同的方式运行,包括接受任意数量的元素 我知道我还可以采取其他方法——我想尽量减

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)