2009-07-07 70 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