流水线函数调用另一个流水线函数 [英] Pipelined function calling another pipelined function

查看:125
本文介绍了流水线函数调用另一个流水线函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个具有两个流水线函数的程序包:

Here's a package with two pipelined functions:

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

重要的是,在/* start *//* end */

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

I can use the package as follows:

select * from table(tq84_pipelined.go);

这一切都很好,但我希望我可以用more_rows的简单调用替换/* start *//* end */之间的行.

This is all fine and dandy, but I hoped I could replace the lines between /* start */ and /* end */ with a simple call of more_rows.

但是,这显然是不可能的,因为它会产生 PLS-00221:'MORE_ROWS'不是过程或未定义.

However, this is obviously not possible, as it generetes a PLS-00221: 'MORE_ROWS' is not a procedure or is undefined.

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

So, my question: is there really no way to shortcut the loop?

编辑

很显然,到目前为止,我的问题还不清楚.

Obviously, from the answers so far, my question was not clear.

如前所述,该包装有效.

The package, as stated works.

但是我对标记/* start *//* end */之间的6条线(即SIX)感到不安.我想用一行替换这些.但是我还没有找到任何办法.

But I am bothered with the 6 (that is: SIX) lines between the markers /* start */ and /* end */. I'd like to replace these with one single line. But I havent found any way doing that.

推荐答案

流水线函数的目的是提供TABLE()函数.我认为没有任何方法可以避免这种情况.不幸的是,我们必须将其输出分配给PL/SQL变量.由于

The point of pipelined functions is to feed TABLE() functions. I don't think there is any way to avoid it. Unfortunately we have to assign its output to a PL/SQL variable. We can't assign a pipelined function to a nested table like this nt := more_rows; due to

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

所以必须SELECT ... FROM TABLE().

对于您的考虑,我有一个略有不同的解决方案.我不知道这是否可以解决您的潜在问题.

I have a slightly different solution for your consideration. I don't know whether it solves your underlying problem.

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中引入了将集合集合在一起的MULTISET UNION语法.

As I'm sure you're aware (but for the benefit of other seekers) the MULTISET UNION syntax for glomming collections together was introduced in Oracle 10g.

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

This version of GO() produces the same output as your original implementation:

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

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

8 rows selected.

SQL>

这篇关于流水线函数调用另一个流水线函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆