Oracle显示游标的使用及游标for循环

时间:2019-03-01 14:32作者:网友投稿

本篇文章给大家介绍oracle显示游标的使用及游标for循环,当查询返回单行记录时使用隐式游标,查询返回多行记录并逐行进行处理时使用显式游标,对本文感兴趣的朋友一起学习吧

下面给大家介绍在什么情况下用隐式游标,什么情况下用显示游标:

1.查询返回单行记录时→隐式游标;

2.查询返回多行记录并逐行进行处理时→显式游标

--显示游标属性

 

 
  1. declare 
  2. CURSOR cur_emp IS SELECT * FROM emp; 
  3. row_emp cur_emp%ROWTYPE; 
  4. BEGIN 
  5. OPEN cur_emp; 
  6. FETCH cur_emp INTO row_emp; 
  7. WHILE cur_emp%FOUND 
  8. LOOP 
  9. dbms_output.put_line(row_emp.empno||'----'||row_emp.ename); 
  10. FETCH cur_emp INTO row_emp; 
  11. END LOOP; 
  12. close cur_emp; 
  13. END; 

--使用显式游标修改数据(给所有的部门经理加薪1000)

 

 
  1. DECLARE 
  2. CURSOR emp_cur IS 
  3. SELECT empno,ename,sal FROM emp WHERE job='MANAGER' FOR UPDATE; 
  4. emp_row emp_cur%ROWTYPE; 
  5. BEGIN 
  6. OPEN emp_cur; 
  7. LOOP 
  8. FETCH emp_cur INTO emp_row; 
  9. IF emp_cur%NOTFOUND THEN 
  10. EXIT; 
  11. ELSE 
  12. UPDATE emp SET sal=sal+1000 WHERE CURRENT OF emp_cur; 
  13. END IF; 
  14. END LOOP; 
  15. COMMIT; 
  16. CLOSE emp_cur; 
  17. END; 

·注意:

1、如果游标打开之前或关闭之后,使用游标属性,Oracle会抛出一个INVALID_CURSOR错误(ORA-01001);

2、如果在第一次fetch后结果集是空的,%found=false,%NotFound=true,%ROWCOUNT=0;

3、如果使用了BULK COLLECT,那么%ROWCOUNT的值可能不是0或1,实际上他返回的是提取到相关集合的行数。

--游标for循环(给所有的部门经理减薪1000)

 

 
  1. DECLARE 
  2. CURSOR emp_cur IS 
  3. SELECT empno,ename,sal FROM emp WHERE job='MANAGER' FOR UPDATE; 
  4. BEGIN 
  5. FOR emp_row IN emp_cur 
  6. LOOP 
  7. UPDATE emp SET sal=sal-1000 WHERE CURRENT OF emp_cur; 
  8. END LOOP; 
  9. COMMIT; 
  10. END; 

--我们可以看到游标FOR循环确实很好的简化了游标的开发,我们不在需要open、fetch和close语句,不在需要用%FOUND属性检测是否到最后一条记录,这一切Oracle隐式的帮我们完成了。

--给经理加薪5000,其他加薪1000

 

 
  1. DECLARE 
  2. CURSOR emp_cur IS 
  3. SELECT * FROM emp FOR UPDATE; 
  4. BEGIN 
  5. FOR emp_row IN emp_cur 
  6. LOOP 
  7. IF emp_row.job='MANAGER' THEN 
  8. UPDATE emp SET sal=sal+5000 WHERE CURRENT OF emp_cur; 
  9. ELSE 
  10. UPDATE emp SET sal=sal+1000 WHERE CURRENT OF emp_cur; 
  11. END IF; 
  12. END LOOP; 
  13. END; 

下面给大家介绍oracle游标cursor简单使用

总共介绍两种游标一种高效使用游标cursor 、sys_refcursor 、 bulk collect

1、cursor游标使用

 

 
  1. /*简单cursor游标  
  2. *students表里面有name字段,你可以换做其他表测试  
  3. */  
  4. --定义  
  5. declare 
  6. --定义游标并且赋值(is 不能和cursor分开使用)  
  7. cursor stus_cur is select * from students;  
  8. --定义rowtype  
  9. cur_stu students%rowtype;  
  10. /*开始执行*/  
  11. begin 
  12. --开启游标  
  13. open stus_cur;  
  14. --loop循环  
  15. loop  
  16. --循环条件  
  17. exit when stus_cur%notfound;  
  18. --游标值赋值到rowtype  
  19. fetch stus_cur into cur_stu;  
  20. --输出  
  21. dbms_output.put_line(cur_stu.name);  
  22. --结束循环  
  23. end loop;  
  24. --关闭游标  
  25. close stus_cur;  
  26. /*结束执行*/  
  27. end; 

执行结果

 

 
  1. SQL> declare 
  2. --定义游标并且赋值(is 不能和cursor分开使用)  
  3. cursor stus_cur is select * from students;  
  4. --定义rowtype  
  5. cur_stu students%rowtype;  
  6. /*开始执行*/  
  7. begin 
  8. --开启游标  
  9. open stus_cur;  
  10. --loop循环  
  11. loop  
  12. --循环条件  
  13. exit when stus_cur%notfound;  
  14. --游标值赋值到rowtype  
  15. fetch stus_cur into cur_stu;  
  16. --输出  
  17. dbms_output.put_line(cur_stu.name);  
  18. --结束循环  
  19. end loop;  
  20. --关闭游标  
  21. close stus_cur;  
  22. /*结束执行*/  
  23. end;  
  24. /  
  25.  
  26. 杨过  
  27. 郭靖  
  28. 付政委  
  29. 刘自飞  
  30. 江风  
  31. 任我行  
  32. 任盈盈  
  33. 令狐冲  
  34. 韦一笑  
  35. 张无忌  
  36. 朵儿  
  37. 谢逊  
  38. 小龙女  
  39. 欧阳锋  
  40. 欧阳锋 

2、sys_refcursor游标使用

 

 
  1. /*  
  2. *游标名:sys_refcursor  
  3. *特别注意赋值方式:for 
  4. *与上重复内容不在叙述  
  5. */  
  6. declare 
  7. stu_cur sys_refcursor;  
  8. stuone students%rowtype;  
  9.  
  10. begin 
  11. --这句赋值方式for  
  12. open stu_cur for select * from students;  
  13. --fetch赋值给rowtype  
  14. fetch stu_cur into stuone;  
  15.  
  16. loop  
  17. dbms_output.put_line(stuone.name||' '||stuone.hobby);  
  18. fetch stu_cur into stuone;  
  19. exit when stu_cur%notfound;  
  20. end loop;  
  21. end; 

执行结果

 

 
  1. SQL> /*  
  2. *游标名:sys_refcursor  
  3. *特别注意赋值方式:for 
  4. *与上重复内容不在叙述  
  5. */  
  6. declare 
  7. stu_cur sys_refcursor;  
  8. stuone students%rowtype;  
  9. begin 
  10. --这句赋值方式for  
  11. open stu_cur for select * from students;  
  12. --fetch赋值给rowtype  
  13. fetch stu_cur into stuone;  
  14. loop  
  15. dbms_output.put_line(stuone.name||' '||stuone.hobby);  
  16. fetch stu_cur into stuone;  
  17. exit when stu_cur%notfound;  
  18. end loop;  
  19. end;  
  20. /  
  21. 杨过 保护小龙女  
  22. 郭靖 修炼降龙十八掌  
  23. 付政委 看小人书  
  24. 刘自飞 编程写代码  
  25. 江风 编程写代码  
  26. 任我行 修炼神功  
  27. 任盈盈 游山玩水  
  28. 令狐冲 行侠仗义  
  29. 韦一笑 吸拾人雪  
  30. 张无忌 修行  
  31. 朵儿 洗浴  
  32. 谢逊 毕生研究屠龙刀  
  33. 小龙女 修炼玉女心经  
  34. 欧阳锋 看小人书 

补充一种循环条件

 

 
  1. declare 
  2. stu_cur sys_refcursor;  
  3. stuone students%rowtype;  
  4. begin 
  5. open stu_cur for select * from students;  
  6. fetch stu_cur into stuone;  
  7. --特别注意循环条件的改变  
  8. --这个条件是发现了在循环  
  9. --与上一个notfound不同的  
  10. while stu_cur%found loop  
  11. dbms_output.put_line(stuone.name||' '||stuone.hobby);  
  12. fetch stu_cur into stuone;  
  13. end loop;  
  14. end; 

--普通的fetch into

 

 
  1. /*普通方式*/  
  2. declare 
  3. cursor myemp_cur is select * from myemp;  
  4. v_myemp myemp%rowtype;  
  5. begin 
  6. open myemp_cur;  
  7. fetch myemp_cur into v_myemp;  
  8. while myemp_cur%found loop  
  9. dbms_output.put_line(v_myemp.ename);  
  10. fetch myemp_cur into v_myemp;  
  11. end loop;  
  12. end; 

--高效的bulk collect

 

 
  1. /*高效bulk collect for*/  
  2. declare 
  3. cursor myemp_cur  
  4. is select * from myemp;  
  5. type myemp_tab is table of myemp%rowtype;  
  6. myemp_rd myemp_tab;  
  7. begin 
  8. open myemp_cur;  
  9. loop  
  10. fetch myemp_cur bulk collect into myemp_rd limit 20;  
  11. for i in 1..myemp_rd.count loop  
  12. dbms_output.put_line('姓名:'||myemp_rd(i).ename);  
  13. end loop;  
  14. exit when myemp_cur%notfound;  
  15. end loop;  
  16. end; 


注:相关教程知识阅读请移步到oracle教程频道。

免责声明:本站所有文章和图片均来自用户分享和网络收集,文章和图片版权归原作者及原出处所有,仅供学习与参考,请勿用于商业用途,如果损害了您的权利,请联系网站客服处理。