2

渡した ID に基づいて sys_refcursor を返す PL/SQL パッケージがあります。いくつかの ID を反復処理し、ID ごとに繰り返される元の結果セットから 1 つの列を含む新しい ref カーソルを作成したいと思います。(一種のクロス集計です。) 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;

作業中、そこから取得できます...何か考えはありますか?または、おそらく私が尋ねるべき質問の明確化。

4

1 に答える 1

3

多数の ID を持っている場合、最初の賞は、ID のバルク インバインドを使用して、SQL クエリを 1 つだけ実行して一度にロットをフェッチすることです。これにはおそらく、単一の ID ではなく ID の PL/SQL テーブルを受け入れるように、 を変更するdashboard_package.visitsか、新しいバージョンのプロシージャを作成する必要があります。visits

dashboard_package を変更する WRT に手を縛られている場合は、一連の 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ことです。1 つの SQL ですべてを行う を用意するだけです。

ちなみに、trim(to_char(sum(v.ly_tot),'9,999,999,999'))に簡略化できますto_char(sum(v.ly_tot),'FM9,999,999,999')。また、代わりにこの形式を使用する'FM9G999G999G999'と、ロケール固有ではなくなります。

于 2009-07-08T05:34:44.483 に答える