5

プロシージャ本体内に動的にカーソルを作成したいのですが、コードの下ではなくfor ループを使用する必要があります。動的カーソルを実行しましたが、for ループを使用できません。

PROCEDURE myprocedure
AS
  LV_TEST_CUR SYS_REFCURSOR;
  LV_QUERY VARCHAR2(200);
  LV_DATE  DATE;
BEGIN
  LV_QUERY:='select sysdate as mydate from dual';
  OPEN LV_TEST_CUR FOR LV_QUERY;
  /*FOR CUR_VAR IN LV_TEST_CUR
  LOOP
  dbms_output.put_line(CUR_VAR.mydate);
  end LOOP;
  */
  LOOP
    FETCH LV_TEST_CUR INTO LV_DATE;
    EXIT
  WHEN LV_TEST_CUR%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(LV_DATE);
  END LOOP;
  CLOSE LV_TEST_CUR;
END myprocedure;

コメント付きコード (for ループ) を使用している場合、エラーが発生します

PLS-00221: プロシージャではないか、未定義です。

動的カーソルで for ループを使用することは可能ですか?

4

3 に答える 3

6

カーソルFORループでカーソル変数を参照することはできません

ただし、select ステートメントを直接使用できます。

create or replace PROCEDURE myprocedure
AS
  LV_TEST_CUR SYS_REFCURSOR;
  LV_QUERY VARCHAR2(200);
  LV_DATE  DATE;
BEGIN
  FOR CUR_VAR IN (select sysdate as mydate from dual)
  LOOP
  dbms_output.put_line(CUR_VAR.mydate);
  end LOOP;

END myprocedure;
/
于 2012-08-28T11:06:05.963 に答える
1

FOR <row> IN <cursor> LOOPこの構文は動的 SQL では使用できません。ドキュメントの例を参照してください。これは、コードがコメントアウトされている場合に使用している方法を示しています。

あなたの例は動的である必要はまったくありませんが、この質問のために単純化しただけだと思います。プレースホルダーがある場合、その値を設定する場所はありません。あなたが持っていた場合:

LV_QUERY:='select sysdate - :days as mydate from dual';
FOR CUR_VAR IN LV_TEST_CUR LOOP
    dbms_output.put_line(CUR_VAR.mydate);
END LOOP;

...その後、バージョンはプレースホルダーFOR ... IN ...に値を割り当てる場所を提供しません。これを行うにdaysは、動的を使用する必要があります。OPEN

LV_QUERY:='select sysdate - :days as mydate from dual';
-- pass '1' as the bind variable
OPEN LV_TEST_CUR FOR LV_QUERY USING 1;
LOOP
    FETCH LV_TEST_CUR INTO LV_DATE;
    EXIT WHEN LV_TEST_CUR%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(LV_DATE);
END LOOP;
CLOSE LV_TEST_CUR;

もちろん、プレースホルダーは必要なく、クエリ文字列を動的に構築しているだけかもしれませんが、それでも制限は適用されます。

于 2012-08-28T11:03:50.290 に答える
0

私の知る限り、カーソル変数または「refcursor」でFORループを使用することはできません。FORループは、ハードコードされたSQLステートメントまたはカーソルでのみ使用されます。「...カーソルFORループでカーソル変数を参照することはできません」と明示的に記載されている
カーソル変数の制限に関するセクションを参照してください。

于 2012-08-28T11:01:06.297 に答える