设为首页 收藏本站
查看: 947|回复: 0

[经验分享] PL/SQL(oracle)4_游标(cursor)

[复制链接]

尚未签到

发表于 2016-7-29 11:02:06 | 显示全部楼层 |阅读模式
  1、游标的概念

cursor:实际上是一块内存工作区,用来存放DML或者select操作的结果。

2、游标的分类:

   隐式游标:声明、打开及管理都是Oracle自动维护的,通常用来处理DML操作或者返回单行的select。

   隐式游标的几个属性:

   %Rowcount:会返回最近执行的一条SQL语句所影响的记录行数。

   %Found:

   %Notfound:

   %isOpen:

   %前缀为SQL

  

   练习:使用替代变量删除指定部门的员工,并显示删除的员工数量。


Begin
Delete From emp Where deptno = &dept;
dbms_output.put_line('删除的员工数为:'||sql%rowcount);
End;
  
  

   显式游标:声明、打开及管理都是需要程序员手动操作的。通常用来处理查询结果是多行或零行的情况。

   1、声明:在declare部分使用:

   Cursor 游标名 Is 查询语句;

   注意:查询语句不能带into子句。
  

cursor emp_cursor is select empno,ename from emp ;
  
  2、打开:

   语法:open 游标名; 写在begin块中。

   打开游标实际上就是相当于执行游标所对应的查询语句,并且把查询结果集放入到内存中。

   3、提取数据:

   语法:fetch 游标名 Into 变量名列表|记录型变量 ,写在begin块,该语句通常是放在一个循环中。

   第一次提取数据之前游标的指针指向第一行,然后每执行一次提取,指针自动向下移动一行。

   注意:变量名列表一定要和游标声明时所对应的查询语句中的列的个数及数据类型保持一致。

   如果变量为记录型变量,那么该变量的内部分量一定要和游标声明时所对应的查询语句中的列的个数及数据类型保持一致。

   游标指针只能向下移动。

   4、关闭游标:

   语法:close 游标名;相当于释放内存。

   显示游标的几个属性:

   %Rowcount:返回的是已经从游标中提取到的记录行数。

   %Found:

   %Notfound:

   %isOpen:

   %前缀为游标名

   练习:使用游标,遍历出所有部门平均工资在1000以上的部门ID,部门名称,平均工资及人数。

   Declare
Cursor avg_cursor Is Select e.deptno,dname,Avg(sal) ,Count(empno)
From emp e ,dept d
Where e.deptno = d.deptno
Group By e.deptno,d.dname
Having Avg(sal)>1000;
v_deptno dept.deptno%Type;
v_dname dept.dname%Type;
v_avgsal emp.sal%Type;
v_count Number;
Begin
Open avg_cursor;
Loop
Fetch Avg_cursor Into v_deptno,v_dname,v_avgsal,v_count ;
Exit When avg_cursor%Notfound;
dbms_output.put_line('部门编号为'||v_deptno'||的部门名称为'||v_dname||',其平均工资为:'||v_avgsal||',人数为'||v_count);
End Loop;
Close avg_cursor;
End;
   

  5、几种方便使用游标的方式。

     a.游标和记录

        1.使用游标名%Rowtype 声明一个记录型变量。

        2.直接使用fetch 游标名 Into 记录型变量名。 

     b.游标式的For循环

       语法:

       For 记录型变量名 In 游标名 Loop

           循环体;

       End Loop;

      

       说明:记录型变量名不用事先声明。

             此种写法,oracle会自动打开游标,从游标中提取数据,关闭游标。

      c.游标式的for循环

        可以直接省略游标的声明,把游标所对应的SElect语句直接放到for循环的in子句中,注意要在两端加上括号。


    练习:使用游标式的For循环,遍历出所有员工姓名,所在部门名称,即使这个员工没有部门。


   Begin
For avg_record In ( Select ename,dname From emp e ,dept d Where e.deptno = d.deptno(+) ) Loop
dbms_output.put_line('部门编号为'||avg_record.ename||'的部门名称为'||avg_record.dname);
End Loop;         
End;
  

   6、带参数的游标

      a、游标声明时和以前有变化,需要在游标名后面指定形式参数列表。

      b、在打开游标时,需要给形式参数赋予响应的实参列表。

      c、提取数据以及关闭游标和先前没有变化。

    7、for Update [Of Column Reference] [Nowait]:该子句用来给游标所对应的查询加锁的。

    8、where Current Of 游标名:用来标示从游标中取出的当前行。

   

    练习:判断每个部门的工资总和,如果大于10000,则给该部门的人员工资增加10%,否则增加20%。


    Declare
Cursor sumsal_cursor Is Select Sum(sal) sumsal,deptno From emp Group By deptno For Update;
Begin
For r_1 In sumsal_cursor Loop
If r_1.sumsal >10000 Then
Update emp Set sal = sal*1.1 Where deptno = r_1.deptno;
Else
Update emp Set sal = sal*1.2 Where deptno = r_1.deptno;
End If;
End Loop;
End ;      
   

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-251123-1-1.html 上篇帖子: 服务器暂时无法响应您的请求 500 Internal Server Error 下篇帖子: oracle 并发读取数据方案比较
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表