当前位置: 代码迷 >> Oracle开发 >> 游标变量可以使用游标FOR循环处理数据吗?该如何解决
  详细解决方案

游标变量可以使用游标FOR循环处理数据吗?该如何解决

热度:121   发布时间:2016-04-24 06:48:25.0
游标变量可以使用游标FOR循环处理数据吗?
--游标变量使用普通for循环输出
SET SERVEROUTPUT ON
DECLARE
  TYPE emp_cur IS REF CURSOR;
  v_emp_cur emp_cur;
  v_emp_record t_myemp%ROWTYPE;
BEGIN
  IF NOT v_emp_cur%ISOPEN THEN
    OPEN v_emp_cur FOR SELECT *FROM t_myemp;
  END IF;
  DBMS_OUTPUT.PUT_LINE('员工ID 姓名 职位 上级ID 生日 工资 奖金 部门ID');
  
  LOOP
    FETCH v_emp_cur INTO v_emp_record;
    EXIT WHEN v_emp_cur%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE(v_emp_record.empno||'  '||v_emp_record.ename||'  '||v_emp_record.job||'  '||v_emp_record.mgr
      ||'  '||v_emp_record.hiredate||'  '||v_emp_record.sal||'  '||v_emp_record.comm||'  '||v_emp_record.deptno);
  END LOOP;
  CLOSE v_emp_cur;
END;
/
--这里没有问题,但是如果用游标for循环的话:
SET SERVEROUTPUT ON
DECLARE
  TYPE emp_cur IS REF CURSOR;
  v_emp_cur emp_cur;
  v_emp_record t_myemp%ROWTYPE;
BEGIN
  IF NOT v_emp_cur%ISOPEN THEN
    OPEN v_emp_cur FOR SELECT *FROM t_myemp;
  END IF;
  DBMS_OUTPUT.PUT_LINE('员工ID 姓名 职位 上级ID 生日 工资 奖金 部门ID');
  FOR v_emp_record IN v_emp_cur  LOOP
    DBMS_OUTPUT.PUT_LINE(v_emp_record.empno||" "||v_emp_record.ename||"  "||v_emp_record.job||"  "||v_emp_record.mgr
    ||"  "||v_emp_record.hiredate||"  "||v_emp_record.sal||"  "||v_emp_record.comm||"  "||v_emp_record.deptno);
  END LOOP;
END;
/
就会报错:
ORA-06550: 第 10 行, 第 23 列: 
PLS-00221: 'V_EMP_CUR' 不是过程或尚未定义
ORA-06550: 第 10 行, 第 3 列: 
PL/SQL: Statement ignored

请问是根本不能这样使用还是我写错了?
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

如果你想在FOR循环中使用游标变量,需要在DECLARE中定义,

DECLARE
   TYPE emp_cur IS REF CURSOR;
   v_emp_cur emp_cur;
   v_emp_record t_myemp%ROWTYPE;

这里不是定义了吗?

我的意思是在定义的时候进行初始化,比如:
CURSOR CR IS SELELCT * FROM TEST.

还有一点是用FOR循环不需要再打开游标,

能给出详细的格式吗?
DECLARE
   TYPE emp_cur IS REF CURSOR;
   v_emp_cur emp_cur;
   v_emp_record t_myemp%ROWTYPE;
   CURSOR v_emp_cur IS SELECT *FROM t_myemp;

这样的方式会报:
PLS-00305: 'V_EMP_CUR' 的前一次使用 (在第 3 行) 与此次使用发生冲突

   CURSOR v_emp_cur IS SELECT *FROM t_myemp;这种方式其实就是定义一个V_EMP_CUR的游标。之所以报错其实是因为 v_emp_cur emp_cur又定义了一个游标,所以会报错,因为你定义了两个同名的游标
------解决方案--------------------
for c in (select ..) loop
   -- 用c.字段/别名 直接取得当前行的某字段/别名的值
end loop;

c 不需要声明 游标不需要声明 不需要打开 不需要关闭

这叫做隐式调用。
  相关解决方案