2010-05-06 8 views
9

Aquí hay un paquete con dos funciones pipeline:función En tubería llamar a otra función pipeline

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 el correspondiente cuerpo de embalaje:

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

Lo importante es que van tipo de llamadas more_rows con el for next in ... entre /* start */ y /* end */

puedo usar el paquete de la siguiente manera:

select * from table(tq84_pipelined.go); 

Esto es todo lo fino y elegante, pero esperaba que pudiera sustituir a las líneas entre /* start */ y /* end */ con una simple llamada de more_rows.

Sin embargo, esto obviamente no es posible, ya que genera un PLS-00221: 'MORE_ROWS' no es un procedimiento o no está definido.

Entonces, mi pregunta: ¿realmente no hay forma de atajar el bucle?

EDITAR

Obviamente, a partir de las respuestas hasta el momento, mi pregunta no era clara.

El paquete, como se indica, funciona.

Pero me molestan las 6 (es decir: SEIS) líneas entre los marcadores /* start */ y /* end */. Me gustaría reemplazar estos con una sola línea. Pero no he encontrado ninguna forma de hacerlo.

Respuesta

7

El objetivo de las funciones segmentadas es alimentar las funciones TABLE(). No creo que haya ninguna forma de evitarlo. Desafortunadamente tenemos que asignar su salida a una variable PL/SQL. No podemos asignar una función canalizado a una tabla anidada como esto nt := more_rows; debido a

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

Así SELECT ... FROM TABLE() que tiene que ser.

Tengo una solución ligeramente diferente para su consideración. No sé si resuelve tu problema subyacente.

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

Como estoy seguro de que está consciente (pero para el beneficio de otros solicitantes) la sintaxis MULTISET Unión para glomming colecciones juntas se introdujo en Oracle 10g.

Esta versión de GO() produce el mismo resultado que su implementación original:

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

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

8 rows selected. 

SQL> 
+0

Gracias por su respuesta. Pero no ayuda mi 'problema' porque con este constructo no solo tengo el 'for ... loop ...la construcción del bucle final, pero también un 'almacenamiento masivo 'adicional. Quiero decir, no es TANTO un problema, ya que puedo vivir con él, pero pensé que sería visualmente más atractivo con una simple llamada de una línea a más filas sin más bucles y lo que no. –

0

Pruebe select column_value line from table(tq84_line.more_rows) es decir, incluya el nombre del paquete en la consulta.

+0

'seleccionar la línea column_value de la tabla (more_rows)' funciona bien. El reemplazo deseado no. –

Cuestiones relacionadas