2009-07-07 13 views
2

J'ai un paquet PL/SQL qui renvoie un sys_refcursor basé sur l'identifiant que vous lui transmettez. Je voudrais parcourir certains identifiants et créer un nouveau curseur ref avec une colonne du jeu de résultats d'origine répété pour chaque identifiant. (. Une sorte de tableau croisé) Une version très simplifiée du bloc PL/SQL ressemble:utiliser le curseur oracle dans un sys_refcursor

create or replace package body dashboard_package is 

    procedure visits(RC in out sys_refcursor, IdNumber varchar2) as 
    BEGIN 

     OPEN RC FOR 


     select * 
    from (
     select cat, cat_order, subcat, label_text 
       , trim(to_char(sum(v.current_month),'9,999,999,999')) current_month 
       , trim(to_char(sum(v.ly_month),'9,999,999,999')) ly_month 
       , trim(to_char(sum(v.ytd_tot),'9,999,999,999')) ytd_tot 
       , trim(to_char(sum(v.lytd_tot),'9,999,999,999')) lytd_tot 
       , trim(to_char(sum(v.ly_tot),'9,999,999,999')) ly_tot 
      from dashboard v 
     where v.id_number = IdNumber 
     group by cat_order, subcat, cat, label_text 

      union all 
      ... 
      ) a 

    order by cat_order, subcat; 

     END; 
END; 

Je pense que si j'avais quelque chose comme ça

create or replace procedure test_refcur is 
    refCursorValue SYS_REFCURSOR; 
begin 
    dashboard_package.visits(refCursorValue,12345); 
    for cursrow in refCursorValue loop 
     dbms_output.put_line(cursrow.ytd_tot); 
    end loop; 
end test_refcur; 
travail

, je pouvais le prendre de là ... des pensées? Ou peut-être une clarification sur la question que je devrais poser.

Répondre

3

Si vous entrez un certain nombre d'ID, le premier prix consistera à exécuter une seule requête SQL pour aller chercher le lot en une seule fois, en utilisant un bulk-bind pour les ID. Cela nécessiterait probablement une modification de dashboard_package.visits ou l'écriture d'une nouvelle version de la procédure visits pour accepter une table PL/SQL d'ID au lieu d'un ID unique.

Si vos mains sont liées WRT modifiant dashboard_package, alors vous pouvez écrire une fonction pipe-line pour retourner les lignes pour un ensemble d'ID:

-- create some helper types for the pipelined function 
create type visitobj as object 
(id    number 
,cat   dashboard.cat%type 
,cat_order  dashboard.cat_order%type 
,subcat   dashboard.subcat%type 
,label_text  dashboard.label_text%type 
,current_month varchar2(13) 
,ly_month  varchar2(13) 
,ytd_tot  varchar2(13) 
,lytd_tot  varchar2(13) 
,ly_tot   varchar2(13)); 
create type visittable as table of visitobj; 

create or replace function test_refcur 
    return visittable deterministic pipelined is 
    refCursorValue SYS_REFCURSOR; 
    cat   dashboard.cat%type; 
    cat_order  dashboard.cat_order%type; 
    subcat   dashboard.subcat%type; 
    label_text  dashboard.label_text%type; 
    current_month varchar2(13); 
    ly_month  varchar2(13); 
    ytd_tot  varchar2(13); 
    lytd_tot  varchar2(13); 
    ly_tot   varchar2(13); 
begin 
    for id in (/*iterate through the IDs*/) loop 
    dashboard_package.visits(refCursorValue, id); 
    loop 
     fetch refCursorValue into cat, cat_order, subcat, label_text, 
           current_month, ly_month, ytd_tot, 
           lytd_tot, ly_tot; 
     exit when refCursorValue%NOTFOUND; 
     pipe row (visitobj (id, cat, cat_order, subcat, label_text, 
          current_month, ly_month, ytd_tot, 
          lytd_tot, ly_tot)); 
    end loop; 
    end loop; 
    return; 
end test_refcur; 

-- now you can simply do this: 
SELECT * FROM TABLE(test_refcur); 

(Bien sûr, « /*iterate through the IDs*/ » serait la méthode que vous voulez à utiliser pour rassembler les ID pour lesquels la fonction doit être appelée - par exemple pourrait être une table PL/SQL d'ID, ou peut-être une autre requête).

Encore une fois, je soulignerais que le «premier prix» est de ne pas faire du tout ce travail supplémentaire - il suffit d'avoir un dashboard_package.visits qui le fait dans un seul SQL. Sur une note de côté, trim(to_char(sum(v.ly_tot),'9,999,999,999')) peut être simplifié en to_char(sum(v.ly_tot),'FM9,999,999,999'). En outre, si vous utilisez plutôt le format 'FM9G999G999G999', il ne sera pas spécifique à l'environnement local.

+0

Merci pour l'astuce sur FM9G999G999G999, c'est génial! Je regarde la fonction de pipeline maintenant. – Lloyd

Questions connexes