【问题标题】:use oracle cursor within a sys_refcursor在 sys_refcursor 中使用 oracle 游标
【发布时间】:2009-07-07 22:20:26
【问题描述】:

我有一个 PL/SQL 包,它根据您传递的 id 返回一个 sys_refcursor。我想遍历一些 id 并创建一个新的 ref 游标,其中包含为每个 id 重复的原始结果集中的一列。 (类似于交叉表。)PL/SQL 块的一个非常简化的版本如下所示:

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;

工作,我可以从那里拿走它...有什么想法吗?或者澄清一下我应该问的问题。

【问题讨论】:

    标签: oracle plsql cursors


    【解决方案1】:

    如果您带着多个 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 的任何方法 - 例如,可以是 PL/SQL 的 ID 表,或者可能是另一个查询)。

    我再次强调,“一等奖”是根本不做任何这些额外的工作 - 只需有一个 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' 格式,它将是非特定于语言环境的。

    【讨论】:

    • 感谢 FM9G999G999G999 的提示,太好了!我现在正在研究管道功能。
    猜你喜欢
    • 1970-01-01
    • 2016-10-25
    • 2014-08-25
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多