流水线函数调用另一个流水线函数

时间:2010-05-06 08:11:35

标签: oracle plsql

这是一个包含两个流水线功能的包:

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

Ant相应的包体:

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_rowsfor next in ...

之间使用/* start */进行调用/* end */

我可以按如下方式使用该包:

select * from table(tq84_pipelined.go);

这一切都很好,但是我希望我可以通过简单的/* start */调用替换/* end */more_rows之间的界限。

然而,这显然是不可能的,因为它产生了一个 PLS-00221:'MORE_ROWS'不是一个程序或未定义

所以,我的问题是:真的没有办法简化循环吗?

修改

显然,从目前为止的答案来看,我的问题并不清楚。

包装,如上所述。

但我对标记/* start *//* end */之间的6条线(即:SIX)感到困扰。我想用一条线替换它们。但我没有找到任何办法。

2 个答案:

答案 0 :(得分: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; 
/

我确信你知道(但是为了其他求职者的利益)在Oracle 10g中引入了用于glomming集合的MULTISET UNION语法。

此版本的GO()产生与原始实现相同的输出:

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

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

8 rows selected.

SQL>

答案 1 :(得分:0)

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