Oracle
 sql >> Base de données >  >> RDS >> Oracle

Fonction PIPELINED imbriquée

Vos fonctions renvoient data_type_1 , et la collection de tables essaie également de consommer cela. Mais les deux ont besoin d'un type de collection, même si vous vous attendez à ce qu'ils ne renvoient qu'une seule valeur (auquel cas il n'y a pas beaucoup de traitement en pipeline). Vous ne pouvez pas diriger directement un type de collection, vous dirigez un membre de la collection. Donc data_type_1 doit être un type scalaire ou objet/enregistrement, et vous avez besoin d'un autre type qui est une collection de ceux-ci.

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

J'ai donc ajouté un type de table de votre data_type_1 existant , et a modifié les définitions de fonction pour renvoyer ce type de table à la place. La pipe row utilise toujours data_type_1 - chacun est une ligne dans le type de table. Votre boucle a besoin d'une requête pour son curseur, pas d'un appel direct à table() , donc j'ai changé ça aussi. Et la ligne pipe row(sub_func); doit également être une boucle similaire sur une requête.

Vous avez seulement marqué ceci comme PL/SQL mais parce que vous avez peut-être l'intention d'appeler main_xyz à partir de SQL brut, et parce que vous appelez les sous-fonctions à partir d'un contexte SQL dans ces boucles, data_type_1 et table_type_1 doivent être créés au niveau du schéma plutôt qu'en PL/SQL. (Cela a un peu changé en 12c mais pas assez pour aider ici).

Si vous vouliez les avoir en tant que types PL/SQL, déclarés dans la spécification du package, vous ne pouviez pas appeler la fonction à partir d'un contexte non PL/SQL et vous deviez remplacer les boucles par un appel à la fonction suivi d'une itération sur la collection renvoyée.