时间:2021-07-21人气:-
本篇文章给大家介绍oracle显示游标的使用及游标for循环,当查询返回单行记录时使用隐式游标,查询返回多行记录并逐行进行处理时使用显式游标,对本文感兴趣的朋友一起学习吧
下面给大家介绍在什么情况下用隐式游标,什么情况下用显示游标:
1.查询返回单行记录时→隐式游标;
2.查询返回多行记录并逐行进行处理时→显式游标
--显示游标属性
- declareCURSORcur_empISSELECT*FROMemp;
- row_empcur_emp%ROWTYPE;BEGIN
- OPENcur_emp;FETCHcur_empINTOrow_emp;
- WHILEcur_emp%FOUNDLOOP
- dbms_output.put_line(row_emp.empno||'----'||row_emp.ename);FETCHcur_empINTOrow_emp;
- ENDLOOP;closecur_emp;
- END;
--使用显式游标修改数据(给所有的部门经理加薪1000)
- DECLARECURSORemp_curIS
- SELECTempno,ename,salFROMempWHEREjob='MANAGER'FORUPDATE;emp_rowemp_cur%ROWTYPE;
- BEGINOPENemp_cur;
- LOOPFETCHemp_curINTOemp_row;
- IFemp_cur%NOTFOUNDTHENEXIT;
- ELSEUPDATEempSETsal=sal+1000WHERECURRENTOFemp_cur;
- ENDIF;ENDLOOP;
- COMMIT;CLOSEemp_cur;
- END;
·注意:
1、如果游标打开之前或关闭之后,使用游标属性,Oracle会抛出一个INVALID_CURSOR错误(ORA-01001);
2、如果在第一次fetch后结果集是空的,%found=false,%NotFound=true,%ROWCOUNT=0;
3、如果使用了BULK COLLECT,那么%ROWCOUNT的值可能不是0或1,实际上他返回的是提取到相关集合的行数。
--游标for循环(给所有的部门经理减薪1000)
- DECLARECURSORemp_curIS
- SELECTempno,ename,salFROMempWHEREjob='MANAGER'FORUPDATE;BEGIN
- FORemp_rowINemp_curLOOP
- UPDATEempSETsal=sal-1000WHERECURRENTOFemp_cur;ENDLOOP;
- COMMIT;END;
--我们可以看到游标FOR循环确实很好的简化了游标的开发,我们不在需要open、fetch和close语句,不在需要用%FOUND属性检测是否到最后一条记录,这一切Oracle隐式的帮我们完成了。
--给经理加薪5000,其他加薪1000
- DECLARECURSORemp_curIS
- SELECT*FROMempFORUPDATE;BEGIN
- FORemp_rowINemp_curLOOP
- IFemp_row.job='MANAGER'THENUPDATEempSETsal=sal+5000WHERECURRENTOFemp_cur;
- ELSEUPDATEempSETsal=sal+1000WHERECURRENTOFemp_cur;
- ENDIF;ENDLOOP;
- END;
下面给大家介绍oracle游标cursor简单使用
总共介绍两种游标一种高效使用游标cursor 、sys_refcursor 、 bulk collect
1、cursor游标使用
- /*简单cursor游标*students表里面有name字段,你可以换做其他表测试
- */--定义
- declare--定义游标并且赋值(is不能和cursor分开使用)
- cursorstus_curisselect*fromstudents;--定义rowtype
- cur_stustudents%rowtype;/*开始执行*/
- begin--开启游标
- openstus_cur;--loop循环
- loop--循环条件
- exitwhenstus_cur%notfound;--游标值赋值到rowtype
- fetchstus_curintocur_stu;--输出
- dbms_output.put_line(cur_stu.name);--结束循环
- endloop;--关闭游标
- closestus_cur;/*结束执行*/
- end;
执行结果
- SQL>declare--定义游标并且赋值(is不能和cursor分开使用)
- cursorstus_curisselect*fromstudents;--定义rowtype
- cur_stustudents%rowtype;/*开始执行*/
- begin--开启游标
- openstus_cur;--loop循环
- loop--循环条件
- exitwhenstus_cur%notfound;--游标值赋值到rowtype
- fetchstus_curintocur_stu;--输出
- dbms_output.put_line(cur_stu.name);--结束循环
- endloop;--关闭游标
- closestus_cur;/*结束执行*/
- end;/
- 杨过
- 郭靖付政委
- 刘自飞江风
- 任我行任盈盈
- 令狐冲韦一笑
- 张无忌朵儿
- 谢逊小龙女
- 欧阳锋欧阳锋
2、sys_refcursor游标使用
- /**游标名:sys_refcursor
- *特别注意赋值方式:for*与上重复内容不在叙述
- */declare
- stu_cursys_refcursor;stuonestudents%rowtype;
- begin
- --这句赋值方式foropenstu_curforselect*fromstudents;
- --fetch赋值给rowtypefetchstu_curintostuone;
- loop
- dbms_output.put_line(stuone.name||''||stuone.hobby);fetchstu_curintostuone;
- exitwhenstu_cur%notfound;endloop;
- end;
执行结果
- SQL>/**游标名:sys_refcursor
- *特别注意赋值方式:for*与上重复内容不在叙述
- */declare
- stu_cursys_refcursor;stuonestudents%rowtype;
- begin--这句赋值方式for
- openstu_curforselect*fromstudents;--fetch赋值给rowtype
- fetchstu_curintostuone;loop
- dbms_output.put_line(stuone.name||''||stuone.hobby);fetchstu_curintostuone;
- exitwhenstu_cur%notfound;endloop;
- end;/
- 杨过保护小龙女郭靖修炼降龙十八掌
- 付政委看小人书刘自飞编程写代码
- 江风编程写代码任我行修炼神功
- 任盈盈游山玩水令狐冲行侠仗义
- 韦一笑吸拾人雪张无忌修行
- 朵儿洗浴谢逊毕生研究屠龙刀
- 小龙女修炼玉女心经欧阳锋看小人书
补充一种循环条件
- declarestu_cursys_refcursor;
- stuonestudents%rowtype;begin
- openstu_curforselect*fromstudents;fetchstu_curintostuone;
- --特别注意循环条件的改变--这个条件是发现了在循环
- --与上一个notfound不同的whilestu_cur%foundloop
- dbms_output.put_line(stuone.name||''||stuone.hobby);fetchstu_curintostuone;
- endloop;end;
--普通的fetch into
- /*普通方式*/declare
- cursormyemp_curisselect*frommyemp;v_myempmyemp%rowtype;
- beginopenmyemp_cur;
- fetchmyemp_curintov_myemp;whilemyemp_cur%foundloop
- dbms_output.put_line(v_myemp.ename);fetchmyemp_curintov_myemp;
- endloop;end;
--高效的bulk collect
- /*高效bulkcollectfor*/declare
- cursormyemp_curisselect*frommyemp;
- typemyemp_tabistableofmyemp%rowtype;myemp_rdmyemp_tab;
- beginopenmyemp_cur;
- loopfetchmyemp_curbulkcollectintomyemp_rdlimit20;
- foriin1..myemp_rd.countloopdbms_output.put_line('姓名:'||myemp_rd(i).ename);
- endloop;exitwhenmyemp_cur%notfound;
- endloop;end;