Oracle
 sql >> Database >  >> RDS >> Oracle

Funzione PIPELINED annidata

Le tue funzioni stanno restituendo data_type_1 , e la raccolta di tabelle sta cercando di consumare anche quello. Ma entrambi hanno bisogno di un tipo di raccolta, anche se ti aspetti che restituiscano un solo valore (nel qual caso non c'è molto punto di pipeline). Non puoi reindirizzare direttamente un tipo di raccolta, devi reindirizzare un membro della raccolta. Quindi data_type_1 dovrebbe essere un tipo scalare o oggetto/record e hai bisogno di un altro tipo che sia una raccolta di quelli.

create type data_type_1 as object (x number, y number)
/

create type table_type_1 as table of data_type_1
/

create or replace package xyz AS
  function main_xyz return table_type_1 pipelined;
  function sub_func return table_type_1 pipelined;
  function sub_func1 return table_type_1 pipelined;
end xyz;
/

create or replace package body xyz as
  function main_xyz return table_type_1 pipelined is
  begin 
    --code
    for rec in (select * from table(sub_func)) loop
      pipe row(data_type_1(rec.x, rec.y));
    end loop;
    for rec in (select * from table(sub_func1)) loop
      pipe row(data_type_1(rec.x, rec.y));
    end loop;
  end;

  function sub_func return table_type_1 pipelined is
    def data_type_1;
  begin 
    --code
    pipe row(def); --def is data_type_1
  end sub_func;

  function sub_func1 return table_type_1 pipelined is
    abc data_type_1;
  begin 
    --code
    loop
      pipe row (abc); --abc is data_type_1
    end loop;
  end sub_func1;
end xyz;
/

Quindi ho aggiunto un tipo di tabella del tuo data_type_1 esistente e modificato le definizioni delle funzioni per restituire invece quel tipo di tabella. La pipe row utilizza ancora data_type_1 - ognuno è una riga nel tipo di tabella. Il tuo ciclo ha bisogno di una query per il suo cursore, non di una chiamata diretta a table() , quindi ho cambiato anche quello. E la pipe row(sub_func); deve anche essere un ciclo simile su una query.

L'hai contrassegnato solo come PL/SQL ma perché potresti voler chiamare main_xyz da SQL semplice e poiché stai chiamando le sottofunzioni da un contesto SQL in quei loop, data_type_1 e table_type_1 devono essere creati a livello di schema anziché in PL/SQL. (Questo ha cambiato leggermente in 12c ma non abbastanza per aiutare qui).

Se volessi averli come tipi PL/SQL, dichiarati nelle specifiche del pacchetto, non potresti chiamare la funzione da un contesto non PL/SQL e dovresti sostituire i loop con una chiamata alla funzione seguito da un'iterazione sulla raccolta restituita.