2016-09-27 91 views
0

要求:我希望從此代碼動態地執行遊標並根據列值將變量var設置爲true或false。PLS-00201:必須在動態sql中聲明標識符'R_CUR'

問題:但是當我運行下面的代碼顯示了我的錯誤:

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'那樣訪問它。完全靜態。您不能訪問名稱動態構建的'variable'。 –

回答

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