PLS-00201: identifier 'R_CUR' must be decl

2019-09-15 04:49发布

Requirement: what I want from this code is to execute the cursor dynamically and set variable var true or false based on column values.

Problem: But while I am running the below code its showing me error:

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;

1条回答
Emotional °昔
2楼-- · 2019-09-15 05:43

The error is valid here. If you look at the execute immediate statement, when its resolved and getting executed, it starts with a begin block. In that begin block the declaration of r_cur is out of scope and hence you get the issue. Yo need to make the r_cur declaration in you begin block as well. See my commented part.

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);
查看更多
登录 后发表回答