2009-07-07 9 views
2

Ich habe ein PL/SQL-Paket, das einen sys_refcursor basierend auf der ID zurückgibt, die Sie übergeben. Ich würde gerne einige IDs durchlaufen und einen neuen Ref-Cursor mit einer Spalte aus der ursprünglichen Ergebnismenge erstellen, die für jede ID wiederholt wird. (. Art einer Kreuztabelle) Eine sehr vereinfachte Version des Blocks PL/SQL wie folgt aussieht:Verwenden Sie Oracle-Cursor in einem 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; 

Ich denke, wenn ich so etwas wie dieses

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; 

Arbeits

hatte, habe ich es nehmen konnte aus da ... irgendwelche Gedanken? Oder vielleicht Klärung der Frage, die ich stellen sollte.

Antwort

3

Wenn Sie mit einer Anzahl von IDs kommen, würde der erste Preis darin bestehen, nur eine SQL-Abfrage auszuführen, um das Los auf einmal zu holen, wobei eine Massenbindung für die IDs verwendet wird. Dies würde wahrscheinlich eine Änderung an dashboard_package.visits erfordern oder eine neue Version der visits Prozedur schreiben, um eine PL/SQL-Tabelle von IDs anstelle einer einzelnen ID zu akzeptieren.

Wenn Ihre Hände WRT modifizieren dashboard_package gebunden sind, dann könnten Sie eine Pipeline-Funktion schreiben, die Zeilen für einen Satz von IDs zurückgegeben:

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

(Natürlich „/*iterate through the IDs*/“ wäre, was Methode Sie wollen zu verwenden, um die IDs zu sammeln, für die die Funktion aufgerufen werden sollte - zB könnte eine PL/SQL-Tabelle von IDs oder vielleicht eine andere Abfrage sein.

Wieder würde ich betonen, dass "der erste Preis" ist, nichts von dieser zusätzlichen Arbeit zu tun - haben Sie einfach eine dashboard_package.visits, die alles in einem SQL erledigt.

Als kleine Randbemerkung kann trim(to_char(sum(v.ly_tot),'9,999,999,999')) auf to_char(sum(v.ly_tot),'FM9,999,999,999') vereinfacht werden. Wenn Sie stattdessen das Format 'FM9G999G999G999' verwenden, wird es nicht länderspezifisch sein.

+0

Danke für den Tipp auf FM9G999G999G999, das ist großartig! Ich schaue jetzt in die Pipeline-Funktion. – Lloyd

Verwandte Themen