2010-05-06 164 views
9

这里有两个流水线功能包:管道函数调用另一个管道函数

create or replace type tq84_line as table of varchar2(25); 
/

create or replace package tq84_pipelined as 

    function more_rows return tq84_line pipelined; 
    function go  return tq84_line pipelined; 

end tq84_pipelined; 
/

蚂蚁相应的包体:

create or replace package body tq84_pipelined as 

    function more_rows return tq84_line pipelined is 
    begin 

     pipe row('ist'); 
     pipe row('Eugen,'); 

     return; 

    end more_rows; 

    function go return tq84_line pipelined is 
    begin 

     pipe row('Mein'); 
     pipe row('Name'); 

     /* start */ 
     for next in (
      select column_value line from table(more_rows) 
     ) 
     loop 
      pipe row(next.line); 
     end loop; 
     /* end */ 

     pipe row('ich'); 
     pipe row('weiss'); 
     pipe row('von'); 
     pipe row('nichts.'); 

    end go; 

end tq84_pipelined; 
/

重要的是,去排序电话more_rows/* start *//* end */

我可以使用包如下:

select * from table(tq84_pipelined.go); 

这是所有罚款和花花公子,但我希望我能与more_rows一个简单的调用替换/* start *//* end */之间的界线。

但是,这显然是不可能的,因为它生成了一个PLS-00221:'MORE_ROWS'不是一个过程,或者是未定义的

所以,我的问题是:真的没有办法捷径循环?

编辑

显然,从到目前为止的答案,我的问题是不明确的。

包装,如上所述的作品。

但我很困扰标记/* start *//* end */之间的6(即:SIX)行。我想用一条线代替它们。但我没有找到任何方式做到这一点。

回答

7

流水线功能的要点是提供TABLE()函数。我不认为有什么办法可以避免它。不幸的是,我们必须将其输出分配给PL/SQL变量。我们无法分配管道函数的嵌套表像这样nt := more_rows;由于

PLS-00653: aggregate/table functions are not allowed in PL/SQL scope 

所以SELECT ... FROM TABLE()它必须是。

我有一个稍微不同的解决方案供您考虑。我不知道它是否解决了你的潜在问题。

create or replace package body tq84_pipelined as 

    function more_rows return tq84_line pipelined is 
    begin 

     pipe row('ist'); 
     pipe row('Eugen,'); 

     return; 

    end more_rows; 

    function go return tq84_line pipelined is 
     nt1 tq84_line; 
     nt2 tq84_line; 
     nt3 tq84_line; 
     nt0 tq84_line; 
    begin 

     nt1 := tq84_line('Mein','Name'); 

     select * 
     bulk collect into nt2 
     from table(more_rows); 

     nt3 := tq84_line('ich','weiss','von','nichts.'); 

     nt0 := nt1 multiset union nt2 multiset union nt3; 

     for i in nt0.first..nt0.last 
     loop 
      pipe row(nt0(i)); 
     end loop; 

     return; 

    end go; 

end tq84_pipelined; 
/

正如我敢肯定,你知道(但对于其他求职者的利益)的MULTISET UNION语法glomming集合在一起,在Oracle 10g中引入的。

这个版本的GO()产生相同的输出作为您最初的实现:

SQL> select * from table(tq84_pipelined.go) 
    2/

COLUMN_VALUE 
------------------------- 
Mein 
Name 
ist 
Eugen, 
ich 
weiss 
von 
nichts. 

8 rows selected. 

SQL> 
+0

感谢您的回复。但它并不能帮助我的'问题',因为在这个构造中,我不仅有'for ...循环......结束循环'结构,但也是一个额外的'批量收集'。我的意思是,这不是一个问题,因为我可以忍受它,但是我认为它在视觉上更具吸引力,只需一行简单的调用即可获得更多的行,而无需进一步的循环,而不需要更多的循环。 – 2010-05-07 02:36:51

0

尝试 select column_value line from table(tq84_line.more_rows) 即在查询中包括包名称。

+0

'选择表(more_rows)COLUMN_VALUE线'工作正常。 所需的替换不。 – 2010-05-06 08:18:24