2016-09-27 7 views
0

要件:カーソルを動的に実行し、変数varを列値に基づいてtrueまたはfalseに設定します。PLS-00201:識別子 'R_CUR'は動的SQLで宣言する必要があります

問題:しかし、私はその私に示すエラー以下のコードを実行していながら:

Error at line 4
ORA-06550: line 1, column 10:
PLS-00201: identifier 'R_CUR' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at line 61`

set serveroutput on; 

DECLARE 
    CURSOR cur 
    IS 
     SELECT EMPNO, 
       ENAME, 
       JOB, 
       MGR 
     FROM emp 
     WHERE EMPNO = 7839; 

    TYPE t_cur IS TABLE OF cur%ROWTYPE; 

    r_cur t_cur; 

    TYPE t IS TABLE OF VARCHAR2 (20); 

    r t 
    := t ('EMPNO', 
      'ENAME', 
      'JOB', 
      'MGR') ; 



    v_if_statement VARCHAR2 (1000); 
    v_sql_statement VARCHAR2 (1000); 
    var VARCHAR2 (10) := 'false'; 
    v VARCHAR2 (10) := 'r'; 
    rc VARCHAR2 (10) := 'r(j)'; 
    vr VARCHAR2 (10) := 'v'; 
    r1 VARCHAR2 (10); 
BEGIN 
    OPEN cur; 

    LOOP 
     FETCH cur BULK COLLECT INTO r_cur; 

     EXIT WHEN cur%NOTFOUND; 
    END LOOP; 

    CLOSE cur; 

    FOR i IN r_cur.FIRST .. r_cur.LAST 
    LOOP 
     FOR j IN r.FIRST .. r.LAST 
     LOOP 
     v_if_statement := 
       'IF r_cur('||i||').' 
      || r (j) 
      || ' ' 
      || 'IS NOT NULL' 
      || ' ' 
      || 'THEN :var:=''true'';' 
      || ' ' 
      || 'dbms_output.put_line(''inside stmt'');' 
      || 'END IF;'; 
      v_sql_statement := 'BEGIN ' || v_if_statement || ' END;'; 

      EXECUTE IMMEDIATE v_sql_statement USING OUT var; 

     DBMS_OUTPUT.put_line ('var : ' || var); 
    END LOOP; 
    END LOOP; 
END; 
+0

これは可能ではありませんが、 'NVL()'を使用して単純なSQL自体で行うことができます。クエリは動的になり、値は動的になります。しかし、カーソルから取り出された列は手前で定義されなければなりません。 –

+0

@MaheswaranRavisankarこんにちは、ここでは、カーソル変数にすべてのデータを手前に取り込んだので、 'r_cur.value_getting_from_tableType'の値を取得したいだけです。 – pulse

+0

あなたは 'r_cur(i).empno'のようにしかアクセスできません。完全に静的です。動的に構築された名前で '変数'にアクセスすることはできません。 –

答えて

1

エラーがここに有効です。 execute immediateステートメントを見ると、解決されて実行されると、beginブロックから始まります。その開始ブロックでr_curの宣言は範囲外であるため、問題が発生します。よろしくお願いします。r_curの宣言をブロックする必要があります。私のコメント部分を参照してください。

FOR j IN r.FIRST .. r.LAST 
     LOOP 
     v_if_statement := 
       'IF r_cur('||i||').' 
      || r (j) 
      || ' ' 
      || 'IS NOT NULL' 
      || ' ' 
      || 'THEN :var:=''true'';' 
      || ' ' 
      || 'dbms_output.put_line(''inside stmt'');' 
      || 'END IF;'; 

      ----**Here when the begin block gets resolved the r_cur decalration is needed.**  
      v_sql_statement := 'BEGIN ' || v_if_statement || ' END;'; 

      EXECUTE IMMEDIATE v_sql_statement USING OUT var; 

     DBMS_OUTPUT.put_line ('var : ' || var); 
+0

私はあなたに確認し返信しましょう。 – pulse

+0

ありがとう、それは働いた。ロジックの偉大なキャッチ:) – pulse

関連する問題