2

より明確にするために編集:


2009 年 1 月 28 日追加: 説明を簡単にするためにコードを単純化しすぎましたが、select ステートメントは非常に長く複雑です。挿入が作成され、2 番目の select は実際には where 句の一部として最初の挿入を調べます。

これが、ループを複数回使用する必要があり、選択を決して組み合わせない理由です。呼び出したい順序で呼び出したときにそれらを実行する必要があります。これにより、元の質問に戻ります別のカーソルでループを再利用する方法はありますか?

再度、感謝します。


私は、カーソルを作成してデータを取得する4つの異なるselectステートメント(おそらくさらに多くのステートメント)を持つパッケージ(Oracle 10)を作成しています。通常、データを取得して For ループを作成すると、すべてがうまくいきます。

私の問題は、4 つの異なる選択があることですが、カーソル c2 が c3 と c4 と同様に同じループを使用できるように、ループを再利用したいということです。これらはすべて、非常に異なる選択から異なる情報を取得するカーソルですが、ループ内のinsertステートメントを使用してすべて同じテーブルに入ります。また、すべての選択を一緒に結合することはできません。ループごとにコミットして順番に実行する必要があります

以下に 4 つのループを使用して例を作成しましたが、ご覧のとおり、すべて同じであり、唯一の違いは次のとおりです。 c1 ループの r と c2 ループの r の場合 ... ループを再利用する方法が必要だと思います。いくつかのアイデアがありましたが、どれもうまくいきませんでした。

 cursor c1 is  select info_a, info_b from table_x where info_g = 77; 
 cursor c2 is  select info-a, info_b from table_x where info_g = 88;
 cursor c3 is  select info-a, info_b from table_y where info_j = 88;
 cursor c4 is  select info-a, info_b from table_y where info_j = 99;


  Begin

     For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c2 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c3 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

     For r in c4 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

   end;

これがより理にかなっていることを願って、ありがとう

編集したところ、いくつかの回答がありました..申し訳ありません。オリジナルは次のようなものでした。

 cursor c1 is  select some_info, other_info from some_table where where some_thing = 'xyz'; 
cursor c2 is select some_info, other_info from some_table where where some_thing = 'abc';

   For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.some_info, r.other_info);
    end loop;
4

5 に答える 5

1

誰かがこれを行う方法を知る必要がある場合、これが機能する答えです。いくつかの調査を行った私のオフィスの別の人から私に与えられたように:

2 つの手順でパッケージを作成しました。1 つ目は複数のカーソル、2 つ目はループです (選択と挿入を簡略化して、それがどのように行われたかを示すだけです)。

Select_Cursor と呼ばれる最初のプロシージャ:

procedure Select_Cursors is 

  the_cursor sys_refcursor;    -- this defines the_cursor as type sys_refcursor  

begin

 open the_cursor for 

     select  application_idn, account_idn     
      from accounts ac,  applications ha
     where  something = somethingelse

 Insert_Cursor ( the_cursor );  
 close the_cursor;

  open the_cursor for 

     select  application_idn, account_idn     
      from accounts ac,  applications ha
     where  somethingfunny = somethingcrazy

  Insert_Cursor ( the_cursor );  
 close the_cursor;


 ...  repeat for every select

 end Select_Cursors; 

Insert_Cursor と呼ばれる 2 番目のプロシージャは次のとおりです。

procedure Insert_Cursor ( p_cursor in sys_refcursor ) is


    begin

       loop
            fetch p_cursor into  application_idn, account_idn ;
            exit when p_cursor%notfound;

            insert into payments (issue_type_des, issued_amt, payment_Type_cde,payment_Status_Cde, created_by, application_idn, account_idn)
                 values          (v_paytype, v_amount, 'S','PE','This Process',  application_idn, account_idn);
       end loop;

       commit;

    end Insert_Cursor;

答えを出して問題を調べてくれたすべての人にもう一度感謝します。

于 2009-01-30T18:34:04.047 に答える
1

または、次のようにします。

cursor c1 is  
select info_a, info_b from table_x where info_g IN (77, 88) UNION ALL
select info-a, info_b from table_y where info_j IN (88, 99);

Begin

     For r in c1 loop
        insert into fun_table (good_info, boring_info) values (r.info_a, r.info-b);
     end loop;
    commit;

END;
于 2009-01-27T20:12:58.893 に答える
0

したがって、次のselectステートメントがあります。

select some_info, other_info from some_table where some_thing = 'xyz'; 
select c2_info, c2_other from c2_table where c2_thing = 'XYZ;'

これを行うには、c1を他の方法では不明なタイプのSYS_REFCURSORとして宣言し、各クエリのすべての列が同じタイプ(またはそれに近い)であることを確認します。行型を使用することはできません。列を個別に宣言する必要があり、すべてのクエリに適用されるジェネリック型です。しかし、以下は機能します。

DECLARE
  C1 SYS_REFCURSOR;
  TableID NUMBER;
  TableName VARCHAR2(240);
BEGIN

  OPEN C1 FOR select CALENDAR_ID, CALENDAR_NAME from CALENDARS;

  LOOP
    FETCH C1 INTO tableid, tablename;
    EXIT WHEN C1%NOTFOUND;
    DBMS_OUTPUT.put_line ('ID: ' || to_char(tableID) || ' -- NAME: ' || TableName);
  END LOOP;
  CLOSE C1;
  OPEN C1 for SELECT INIT_ID, NAME FROM INITS;  
  LOOP
    FETCH C1 INTO tableid, tablename;
    EXIT WHEN C1%NOTFOUND;
    DBMS_OUTPUT.put_line ('ID: ' || to_char(tableID) || ' -- NAME: ' || TableName);
  END LOOP;
  CLOSE C1;
END;
于 2009-01-27T19:54:33.547 に答える
0

ただ行う:

begin
  insert into cool_table 
  ( neat_info 
  , boring_info)
  select some_info
  ,      other_info 
  from some_table 
  where some_thing = 'XYZ';
end;

カーソル ループは必要ありません。

于 2009-01-27T20:06:31.323 に答える
0

カーソル クエリを動的に作成して、1 つのカーソルのみを使用しないのはなぜですか?

77、88、および 99 は、パラメーターからストアド プロシージャに渡されると思います。

cursor c1 is  
select info_a, info_b from table_x where info_g in( 77, 88)
UNION
select info-a, info_b from table_y where info_j in (88, 99)
...
于 2009-01-27T20:18:08.727 に答える