我有以下问题: 我的基表中的每一行都有一个标志列(下面列表中的“flg”)和一个函数参数列(“arg”)。如果在#N 行中标志为“Y”,则必须调用函数;之后,它将返回,比方说,一列(实际上是一堆,但我会尽可能简化)。最后,行 #N 应该转换为子表 - 行 #N 和函数返回的列的完全联接。 如果标志为“N”,则行 #N 的结果应为该行本身加上“函数返回列”中的 NULL。
这是一个例子:
create or replace package SIEBEL.TEST_PACKAGE as
type ret_type is table of number;
function testFunc(inp number)
return ret_type
pipelined;
end TEST_PACKAGE;
/
create or replace package body SIEBEL.TEST_PACKAGE is
function testFunc(inp number)
return ret_type
pipelined
is
i number;
begin
dbms_output.put_line('Function call, arg = ' || to_char(inp));
if (inp is null OR inp = 0) then
pipe row (null);
else
for i in 1..inp loop
pipe row (i);
end loop;
end if;
end testFunc;
end TEST_PACKAGE;
/
with base_table as
(
select 'Shall invoke' col0, 'Y' flg, '2' arg from dual
union
select 'Shall not invoke' col0, 'N' flg, '0' arg from dual
)
select * from base_table t0, table(siebel.test_package.testFunc(t0.arg)) t1;
它将返回我真正想要的:
COL0 | FLG | ARG | COLUMN_VALUE
--------------------------------------------
Shall invoke | Y | 2 | 1
Shall invoke | Y | 2 | 2
Shall not invoke | N | 0 |
问题是,即使对于“N”标志,该函数仍然被调用 - 数据库输出将显示
Function call, arg = 2
Function call, arg = 0
如果在现实世界中,我有数百 strip 有“Y”标志的记录,大约 100K strip 有“N”标志的记录。另外,我的实际函数要复杂得多,并且其 namespace 中有很多内容,因此每个函数调用对于性能而言都至关重要。
我真正想要的是示例的数据库输出:
Function call, arg = 2
我可以通过
实现它with base_table as
(
select 'Shall invoke' col0, 'Y' flg, '2' arg from dual
union
select 'Shall not invoke' col0, 'N' flg, '0' arg from dual
)
select t.*, t1.column_value
from base_table t, table(SIEBEL.TEST_PACKAGE.testFunc(t.arg)) t1
where t.flg = 'Y'
union all
select t.*, null as column_value
from base_table t
where t.flg = 'N';
但随后所有索引都变得毫无用处 - 每个“order by”指令都需要很长时间才能完成。
请帮助我实现函数调用所需的行为,并仍然保存原始行顺序。
如果有什么不清楚的地方,请随时问我。
最诚挚的问候, 阿列克谢
最佳答案
对于 flag = "N",如果您有条件加入,则不会调用该函数
set serveroutput on
with base_table as
(
select 'Shall invoke' col0, 'Y' flg, '2' arg from dual
union
select 'Shall not invoke' col0, 'N' flg, '0' arg from dual
)
select * from base_table t0
left join table( test_package.testFunc(t0.arg) ) t1 on (t0.flg = 'Y');
脚本输出
Package created.
Package body created.
COL0 FLG ARG COLUMN_VALUE
---------------- --- --- ------------
Shall invoke Y 2 1
Shall invoke Y 2 2
Shall not invoke N 0
3 rows selected.
服务器输出:
Function call, arg = 2
关于oracle - 如何有条件地连接 Oracle SQL 中的表函数(该函数以主表行列作为参数),而无需过多的函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29411396/