PL*SQLでFETCHする際のFOR文使用の注意点。

PL*SQLでFETCHする際のFOR文使用の注意点。

「FOR IN LOOP」を使用すると、カーソルのOPEN及びCLOSEが暗黙的に行われるので便利だが、レコード変数のスコープがFORループ内になってしまう。

CREATE OR REPLACE PACKAGE BODY PKG_HOGE AS
  rt_hoge  hogehoge%ROWTYPE;                  -- レコード

  PROCEDURE PROC_A
  IS
    CURSOR csr_hoge IS SELECT * FROM hogehoge;  -- カーソル
  BEGIN
    FOR rt_hoge IN csr_hoge LOOP
      PROC_B();
    END LOOP;
  END;

  PROCEDURE PROC_B
  IS
  BEGIN
    -- rt_hoge の値はFORループ外部から参照できない(参照しても空)
    DBMS_OUTPUT.PUT_LINE('*****' || rt_hoge.項目名 || '*****');
  END;
END;

仮にFORループ外から参照が必要な場合、一旦レコード変数で受けて、パブリック変数等にMOVEする等の対応が必要。

CREATE OR REPLACE PACKAGE BODY PKG_HOGE AS
  rt_hoge  hogehoge%ROWTYPE;                  -- レコード

  PROCEDURE PROC_A
  IS
    rt_pri_hoge  hogehoge%ROWTYPE;              -- レコード
    CURSOR csr_hoge IS SELECT * FROM hogehoge;  -- カーソル
  BEGIN
    FOR rt_pri_hoge IN csr_hoge LOOP
      rt_hoge := rt_pri_hoge;
      PROC_B();
    END LOOP;
  END;

  PROCEDURE PROC_B
  IS
  BEGIN
    -- rt_hoge の値は参照可能
    DBMS_OUTPUT.PUT_LINE('*****' || rt_hoge.項目名 || '*****');
  END;
END;