用户定义的函数,带有任意参数列表

时间:2018-07-10 15:49:54

标签: sql-server tsql sql-server-2012 parameter-passing user-defined-functions

Coalcece()内置函数接受任意数量的参数。

在SQL Server 2012中是否可以编写具有相同语法的用户定义函数?我不想使用表格变量或逗号分隔的列表。

我想实现一个Coalesce()函数,该函数返回传入的LOWEST非null元素,而不是传入的FIRST非null元素。这是为了满足新的用户需求。 Coalesce()不需要创建表变量,并且由于我要用新逻辑替换现有的Coalesce()调用,因此我想编写新函数以使其行为相同,包括接受任意数量的元素。 / p>

我知道我可以在这里采取其他方法-我想尽量减少重写次数。

2 个答案:

答案 0 :(得分:1)

是的,有可能。只是不在T-SQL中。您需要编写CLR函数

答案 1 :(得分:0)

  

如果可以避免,我不想使用表变量或逗号分隔的列表。

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);

DBFiddle Demo

输出:

┌────┬───┬──────┬──────┬──────┬───────────────────────────────┬────────┐
│ 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 │
└────┴───┴──────┴──────┴──────┴───────────────────────────────┴────────┘

编辑:

否,不可能使用变量{COLAESCE”定义UDF。您可以获得的最好的是:

LOWEST2(a1, a2)
LOWEST3(a1, a2, a3)
LOWEST4(a1, a2, a3, a4)
...
LOWESTn(a1, a2, a3, a4, ..., an)

请注意,函数名称不同。另外,您需要使用能够满足大多数情况甚至是sqlvariant的数据类型。