plsql引用游标错误

时间:2014-01-07 12:10:53

标签: oracle plsql syntax-error

plsql引用游标:

DECLARE
  TYPE cur IS REF CURSOR;
  c1   cur;
  emp  emp_table%ROWTYPE;
  stmt VARCHAR2(200) := 'select * from emp_table';
  CURSOR c2 IS
    SELECT DISTINCT dept_id FROM emp_table;
BEGIN

  FOR i IN c2 LOOP
    dbms_output.put_line('the department no is ' || i.dept_id);
  END LOOP;

  IF i.dept_id IS NULL THEN
    OPEN c1 FOR stmt;
  ELSE
    stmt := stmt || ' where dept_id = i.dept_id';
    OPEN c1 FOR stmt USING i.dept_id;
  END IF;

  LOOP
    FETCH c1 INTO emp;
    EXIT WHEN c1%NOTFOUND;
    dbms_output.put_line(c1.dept_id || ' , ' || c1.emp_name || ' , ' || c1.emp_sal);
  END LOOP;

  CLOSE c1;

END;
/
我得到的错误是

**ORA-06550: line 11, column 4:                           
PLS-00201: identifier 'I.DEPT_ID' must be declared                 
ORA-06550: line 11, column 1:                 
PL/SQL: Statement ignored                      
ORA-06550: line 19, column 25:                     
PLS-00487: Invalid reference to variable 'C1'                   
ORA-06550: line 19, column 1:                          
PL/SQL: Statement ignored                       
06550. 00000 -  "line %s, column %s:\n%s"                    
*Cause:    Usually a PL/SQL compilation error.                           
*Action:**                  

请帮我解决这个错误。请告诉我学习plsql的好链接。

3 个答案:

答案 0 :(得分:1)

stmt := stmt || ' where dept_id = i.dept_id';  

应该是

stmt := stmt || ' where dept_id = :1';  

答案 1 :(得分:0)

除了上面的错误之外,您尝试在声明它的循环之外使用i.dept_id

应该是这个:

FOR i IN c2 LOOP          
    DBMS_OUTPUT.PUT_LINE('the department no is ' || i.dept_id);              
    IF i.dept_id IS NULL THEN 
        OPEN c1 FOR stmt;  
    ELSE   
        stmt := stmt || ' where dept_id = :p1';              
        OPEN c1 FOR stmt USING i.dept_id;           
    END IF;                  
    LOOP                     
        FETCH c1 INTO emp;          
        EXIT WHEN c1%NOTFOUND;      
        DBMS_OUTPUT.PUT_LINE(c1.dept_id||' , '||c1.emp_name||' , '||c1.emp_sal);          
    END LOOP;  
    CLOSE c1;
END LOOP;  

答案 2 :(得分:0)

不完全回答您的问题,您可以缩短代码。 您有两个可以合并为一个的查询。

查询1(如果i.dept_id为空)

select * 
from emp_table;

查询2(如果i.dept_id不为空)

select * 
from emp_table 
where dept_id=i.dept_id;

您可以轻松地为这两种情况创建一个查询:

select * 
   from emp_table 
   where (i.dept_id is null or dept_id=i.dept_id);