创建具有不确定数量参数的 Oracle 函数/宏
Posted
技术标签:
【中文标题】创建具有不确定数量参数的 Oracle 函数/宏【英文标题】:Create Oracle function/macro with an undeterminate number of arguments 【发布时间】:2015-01-07 15:45:32 【问题描述】:是否可以创建一个 Oracle PL/SQL 函数或宏来帮助我生成一些代码?
例如
sumnull(a,b)
会回来
coalesce(a, 0) + coalesce(b, 0) +
(case when coalesce(a, b) is not null then 0 else null end)
和
sumnull(a,b,c)
会返回
coalesce(a, 0) + coalesce(b, 0) + coalesce(c, 0) +
(case when coalesce(a, b, c ) is not null then 0 else null end)
但是 sumnull 也可以接受超过 3 个参数 (a,b,c,d,e.....)
【问题讨论】:
【参考方案1】:在 C varargs
意义上(例如),您不能有可变数量的参数。你可以重载一个函数,这样你就有一个需要 2 的版本,另一个需要 3 的版本,等等,这样维护起来会很痛苦;或者有一长串值,它们都默认为零:
create or replace function sumnull (p_1 number default null, p_2 number default null,
p_3 number default null, p_4 number default null /*, etc. */)
return number as
begin
return coalesce(p_1, 0) + coalesce(p_2, 0)
+ coalesce(p_3, 0) + coalesce(p_4, 0) /* + etc. */;
end;
/
select sumnull() from dual;
SUMNULL()
----------
0
select sumnull(null) from dual;
SUMNULL(NULL)
-------------
0
select sumnull(1,null,7,9) from dual;
SUMNULL(1,NULL,7,9)
-------------------
17
但是你仍然必须在某个时候设置一个上限,如果你尝试发送太多参数,它会出错,PLS-00306。重复这些子句会有点乏味并且可能容易出错。
另一种选择是传递一组值,例如:
create or replace function sumnull (p_values sys.odcinumberlist)
return number as
l_total number := 0;
begin
if p_values is null or p_values.count = 0 then
return l_total;
end if;
for i in 1..p_values.count loop
l_total := l_total + coalesce(p_values(i), 0);
end loop;
return l_total;
end;
/
那么你可以这样称呼它:
select sumnull(null) from dual;
SUMNULL(NULL)
-------------
0
select sumnull(sys.odcinumberlist()) from dual;
SUMNULL(SYS.ODCINUMBERLIST())
-----------------------------
0
select sumnull(sys.odcinumberlist(1,null,7,9)) from dual;
SUMNULL(SYS.ODCINUMBERLIST(1,NULL,7,9))
---------------------------------------
17
您也可以将列名作为更大查询的一部分传递;在此处对虚拟数据使用 CTE:
with t as (select 1 as a, null as b, 7 as c, 9 as d from dual)
select sumnull(sys.odcinumberlist(a, b, c, d)) from t;
SUMNULL(SYS.ODCINUMBERLIST(A,B,C,D))
------------------------------------
17
您当然可以在 SQL 级别定义自己的集合类型,built-in sys.odcinumberlist
只是方便。
【讨论】:
谢谢!所以出于好奇,Coalesce() 如何获得不确定数量的参数? 我可以用列名代替数字吗? 嗯,好问题;我想它是在较低级别实现的,在 C 或其他核心数据库代码的一部分中,而不是在 PL/SQL 中。虽然这增加了我想使用 Java 函数的可能性。我认为 coalesce 仍然限制为 1000 个参数,这是值列表的正常限制。 @Stephane - 是的,我在答案中添加了一个示例。以上是关于创建具有不确定数量参数的 Oracle 函数/宏的主要内容,如果未能解决你的问题,请参考以下文章