2009-07-07 187 views
2

我有一個PL/SQL包,它基於您傳遞它的id返回一個sys_refcursor。我想遍歷一些ID並創建一個新的引用遊標,其中每個ID都重複一個原始結果集。 (排序交叉選項卡)的PL/SQL塊的一個非常簡化的版本是這樣的:在sys_refcursor中使用oracle遊標

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; 

我想,如果我有這樣的事情

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; 

的工作,我可以把它從那裏...有什麼想法?或者也許可以澄清我應該問的問題。

回答

3

如果您使用大量ID,那麼首要獎勵就是隻運行一個SQL查詢以便一次性獲取批次,並使用批量綁定中的ID。這可能需要對dashboard_package.visits進行修改,或者編寫新版本的visits過程來接受ID的PL/SQL表而不是單個ID。

如果你的雙手被縛WRT修改dashboard_package,那麼你可以寫一個管道函數返回的行的集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); 

(當然,「/*iterate through the IDs*/」將是你想要的任何方法用於收集函數應該被調用的ID--例如可以是ID的PL/SQL表,或者可能是其他查詢)。

我再次強調,「一等獎」是不做任何額外的工作 - 只需要一個dashboard_package.visits即可在一個SQL中完成所有工作。

在附註中,trim(to_char(sum(v.ly_tot),'9,999,999,999'))可以簡化爲to_char(sum(v.ly_tot),'FM9,999,999,999')。另外,如果使用'FM9G999G999G999'格式,則它將是非特定於語言環境的。

+0

感謝您提供FM9G999G999G999的提示,太棒了!我正在研究管道功能。 – Lloyd 2009-07-09 14:44:39