我会发布一个简单的例子,它实际上是有效的,只是为了得到我想要实现的内容的近似图片:
这是'内部'函数,它从一些表中获取数据,称为test_tab
:
create or replace function test_inner RETURN num_typ PIPELINED
IS
BEGIN
FOR cur in (
SELECT x FROM test_tab
)
LOOP
PIPE ROW(cur.x);
END LOOP;
END;
/
这是'外部'函数,它使用inner
函数的结果并适当地转换它们:
create or replace function test_outer RETURN num_typ PIPELINED
IS
BEGIN
FOR x IN (
SELECT * FROM table(test_inner())
)
LOOP
PIPE ROW(x.column_value * 2);
END LOOP;
END;
/
以下是我如何使用它:
begin
execute immediate 'insert into test_tab(x) values(1)';
execute immediate 'insert into test_tab(x) values(2)';
execute immediate 'insert into test_tab(x) values(3)';
FOR x IN (
select * from table(test_outer())
) LOOP
DBMS_OUTPUT.put_line(x.column_value);
END LOOP;
end;
/
问题是Oracle似乎忽略了test_inner
函数。当它被单独调用时,它会“看到”在执行之前插入的数据。但当它被称为test_outer
的一部分时,它不会返回任何数据,或者根本不会被调用。
就像我说的,上面的例子会起作用。但我的情况有点复杂,所以我不能完全发布它。
答案 0 :(得分:3)
您发布的测试用例不会重现您声称看到的问题。所以它不是一个测试用例。
@AlexPoole为您提供了一些其他想法。基本上没有什么可以做的,除非你能发布一个更好的测试用例,因为你不能发布所有的东西(而且我们不想通过数百行其他人的代码 - 我得到足够的调试我自己的东西)。
制作一个糟糕的测试用例并不是浪费时间。至少你可以排除某些事情:它与一个流水线函数调用另一个无关。因此,在您的具体实施中,它显然是一些东西。也许不是在内部函数逻辑中,而是它们如何被调用,它们使用的数据或基础结构的其他部分。
您所能做的就是分析各个部分。从核心组件开始,然后构建,添加其他组件,直到找到中断的位。是的,这是一项乏味的苦差事。但是从您的评论中可以看出,您已经完成了这个过程。
我标记这个CW,因为它不是问题的答案,只是一个扩展的评论。
答案 1 :(得分:-1)
您的两个流水线函数实际上都是语法错误:您缺少 RETURN