2016-11-08 12 views
2

Oracle PL/SQLの新機能です。私は最初にテーブルの列からデータを取得し、変数に代入するプロシージャを作成しようとしています。結果の各行/値について、別のクエリを実行し、この新しいクエリの結果をループし、さまざまな挿入と更新を実行します。その後、私は外側のループに戻り、シーケンスを続行します。次のように私の試みは次のとおりです。Oracle PL/SQLプロシージャのbeginセクションの後にカーソルを宣言する方法

CREATE OR REPLACE PROCEDURE CMSADMIN.Proc_RFC_UPD_NEW_MRSP 
IS 

    ecode NUMBER; 
    emesg VARCHAR2(200); 

    cursor y IS (select distinct cod_unicom FCODE from RFC_UPD_NEW_MRSP_POOL); 

BEGIN 

for t in y loop 

    cursor X IS ( 
       SELECT DISTINCT s.NIF PREMISE,a.COD_UNICOM READING, A.COD_LECT_AREA AREA 
       FROM SUMCON s, LECT_AREAS a 
       WHERE a.COD_UNICOM = t.FCODE 
       AND s.NUM_SUM IN (select num_sum from RFC_UPD_NEW_MRSP_POOL where cod_unicom = t.FCODE) 
       ); 


     for met in x loop 

      /* Store record trace*/ 
      INSERT into RFC_UPD_NEW_MRSP(NIF, COD_UNICOM,COD_LECT_AREA, USUARIO, F_ACTUAL, PROGRAMA) 
      values (met.PREMISE, met.READING, met.AREA, USER, SYSDATE,'RFC_MRSP_FPL'); 

      UPDATE fincas_per_lect fp 
      SET 
      FP.NUM_MRSP = MET.READING, 
      fp.AOL_FIN=0, 
      fp.NUM_ITIN =0, 
      fp.USUARIO = user, fp.PROGRAMA = 'RFC_MRSP_FPL', fp.F_ACTUAL = sysdate 
      WHERE Fp.NIF=met.PREMISE; 

      UPDATE apmedida_ap fp 
      SET 
      FP.NUM_MRSP = MET.READING, 
      fp.USUARIO = user, fp.PROGRAMA = 'RFC_MRSP_FPL', fp.F_ACTUAL = sysdate 

       WHERE Fp.NIF_apa = met.PREMISE; 

      UPDATE FINCAS fp 
      SET AREA_LECT = MET.AREA, 
       fp.USUARIO = user, fp.PROGRAMA = 'RFC_MRSP_FPL', fp.F_ACTUAL = sysdate 
       WHERE NIF = met.PREMISE; 

     end loop; 

end loop; 

    COMMIT; 
    dbms_output.put_line('The procedure Proc_RFC_UPD_NEW_MRSP executed successfully'); 

EXCEPTION 
    WHEN OTHERS THEN 
     ecode := SQLCODE; 
     emesg := SQLERRM; 
     dbms_output.put_line('The procedure Proc_RFC_UPD_NEW_MRSP fail with folowing error '|| TO_CHAR(ecode) || ' and error message: ' || emesg); 
     NULL; 
end Proc_RFC_UPD_NEW_MRSP; 

私はBEGIN内側のforループの後に別のカーソルを持って見ることができるように。これは許可されていますか?スクリプトが期待どおりに動作しません。何が問題なの?任意の助けに感謝

+0

更新のためにネストされたループを避ける。ほとんどの場合、ネストされたpl_sqlループの代わりにjoinを使用できます。バルク/フォールも考慮してください。 – Rusty

+0

xカーソル内のsqlを内部結合で置き換えてみませんか?あなたは別個なので、内部結合は返された行の数を変更しませんが、より良い実行します。 – Rusty

+0

変数 'x'、' y'、 't'の名前は本当ですか?私はあなたの例のようにネストする必要がない限り、それぞれ数値とカーソルループに 'i'と' r'を使います。しかし、それを避けるために非常に努力します。そうでなければ、私は常に意味のある名前を使います。かなり混乱しています。 –

答えて

1

これを行うには、あなたが新しいブロックに宣言する必要があるでしょう:あなただけと一緒にこのカーソルを宣言できない理由しかし

for t in y loop 
    DECLARE 
    cursor X IS ( 
       SELECT DISTINCT s.NIF PREMISE,a.COD_UNICOM READING, A.COD_LECT_AREA AREA 
       FROM SUMCON s, LECT_AREAS a 
       WHERE a.COD_UNICOM = t.FCODE 
       AND s.NUM_SUM IN (select num_sum from RFC_UPD_NEW_MRSP_POOL where cod_unicom = t.FCODE) 
       ); 
    BEGIN 

     for met in x loop 
... 
     end loop; 
    END; 

を、私は非常に表示されません

FOR met IN x(t.FCODE) LOOP 
:あなたはその後、thuslyカーソルを参照することができ

cursor X (p_FCODE RFC_UPD_NEW_MRSP_POOL.cod_unicom%TYPE) IS ( 
      SELECT DISTINCT s.NIF PREMISE,a.COD_UNICOM READING, A.COD_LECT_AREA AREA 
      FROM SUMCON s, LECT_AREAS a 
      WHERE a.COD_UNICOM = p_FCODE 
      AND s.NUM_SUM IN (select num_sum from RFC_UPD_NEW_MRSP_POOL where cod_unicom = p_FCODE) 
      ); 

:yは、パラメータで定義されたカーソル

+0

こんにちは。あなたのご意見ありがとうございます。私は 'WHERE a.COD_UNICOM = t.FCODE'を使用しているので、カーソルyと一緒に宣言することはできません。 –

+0

' t.FCODE'は、最初のカーソルで実行されたクエリから得られる値です –

+0

更新された答えを見てください。 – DCookie

0
declare 
    cursor cur1 is 
    ... 
begin 
    ... 

    declare 
    cursor cur2 is 
    ... 
    begin 
    end; 
end; 
関連する問題