Конвейерная функция, вызывающая другую конвейерную функцию

Вот пакет с двумя конвейерными функциями:

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 с for next in ... между /* start */ и /* end */

Я могу использовать пакет следующим образом:

select * from table(tq84_pipelined.go);

Это все великолепно, но я надеялся, что мог заменить строки между /* start */ и /* end */ с простым вызовом more_rows.

Однако это, очевидно, не возможно, поскольку это генерирует PLS-00221: 'MORE_ROWS' не является процедурой или не определен.

Так, мой вопрос: нет ли действительно никакой путь к ярлыку цикла?

Править

Очевидно, из ответов до сих пор, мой вопрос не был ясен.

Пакет, как указанные работы.

Но я побеспокоен 6 (который является: ШЕСТЬ) строки между маркерами /* start */ и /* end */. Я хотел бы заменить их одной одной строкой. Но я не нашел способа делать это.

9
задан René Nyffenegger 6 May 2010 в 08:26
поделиться

2 ответа

Смысл конвейерных функций заключается в передаче функций 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 для объединения коллекций вместе был введен в 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>
7
ответ дан 4 December 2019 в 23:05
поделиться

Попробуйте выбрать строку column_value из таблицы (tq84_line.more_rows) т.е. включить имя пакета в запрос.

0
ответ дан 4 December 2019 в 23:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: