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

[经验分享] oracle游标的简单使用规则

[复制链接]

尚未签到

发表于 2016-7-25 09:29:23 | 显示全部楼层 |阅读模式
  
oracle游标
  
         最近对oracle 中的游标有了新的认识所以写出来给大家分享分享。
在通过select 语句查询时,返回的结果通常是多行记录组成的集合。这对于程序设计语言而言,并不能够处理以集合形式返回的数据,为此,sql提供了游标机制。游标充当指针的作用,使应用程序设计的语言一次只能处理查询结果的一行。在oracle中可以使用显式和隐式两种游标。
同时对于PL/SQL程序中所发出的dml 和 select 语句,oracle 都会自动的声明“隐式游标”。为了处理select 语句返回一组记录,需要在PL/SQL程序中声明和处理“显式游标”。
隐式游标

在执行sql语句时,oracle服务器会自动的创建一个隐式的游标。这个游标是内存中处理该语句的工作区域,其中存储了执行sql语句的结果。通过游标的属性可知道sql的执行结果,以及游标的状态信息。
游标的主要属性:
   %Foundboolean 布尔型,如果sql影响了一行,则为true 否则为false;
   %NotFoundboolean 布尔型 ,与Found相反;
   %IsOpenboolean 布尔型,当游标已达开始返回true 否则返回false;
   %RowCount数字型属性返回sql影响的行数。
注:当使用隐式游标的属性时,属性前要加上sql,因为oracle在创建隐式游标时,默认的游标名为sql
         Boolean布尔类型的值不能用dnms_output.putline()输出
ü  隐式游标的使用
SQL> begin

  2 update emp

  3  setsal=800

  4 where  empno=1;

  5  ifsql%notfound then

  6 dbms_output.put_line('未更新记录');

  7  else

  8 dbms_output.put_line('更新'|| sql%rowcount||'条');

  9  endif;

10  end;/
注:游标的属性信息总是反应最新的sql 语句处理结果。
SQL> declare

  2  empremp%rowtype;

  3  

  4 begin

  5  updateemp

  6  setsal=800

  7 where  empno=1;

  8  ifsql%notfound then

  9 dbms_output.put_line('未更新记录');

10  else

11 dbms_output.put_line('更新'|| sql%rowcount||'条');

12  endif;

13 select * into empr from emp where empno=1;

14 dbms_output.put_line('更新'|| sql%rowcount||'条');

15  end

16  ;

17  /


更新1条

更新1条


PL/SQL procedure successfullycompleted


SQL>
ü  另一种隐式游标cursor(光标)
Cursor for loop

begin

    for emps in (select empno,ename,job,hiredate,sal,comm,deptno  from emp)

   loop   dbms_output.put_line(emps.empno||emps.ename||emps.job||emps.hiredate||emps.sal||emps.comm);

    end loop;

end ;

使用 cursor forloop 遍历查询的结果集


显式游标

显式游标是在PL/SQL程序中使用包含SELECT语句来声明的游标。如果需要处理从数据库中检索的一组记录,则可以使用显式游标。使用先是游标处理数据需要四个PL/SQL步骤:
ü  声明游标
声明游标就是通过定义游标的名称、游标特征来声明游标,以及打开游标后就可用来调用查询语句。使用游标之前必须先声明游标。声明游标的语法如下:
Cursor 游标名字[(参数)[参数]…][return 返回的类型]is  查询的语句
Declare
Cursor  empc (empno_p numberdefault  1) is
Select* from emp where empno=empno_p;
注: number 不能有长度 否则报错
ü  打开游标
打开游标就是执行声明游标时所指定的查询语句。游标必须声明后才能打开。打开游标也就是调用游标中的select语句。
Open 游标名称;
例如打开上面的的游标
Openempc;

ü  检索数据

检索数据就是从检索到的结果集中获取数据保存到变量中,以便在程序中进行处理。检索数据就是使用fetch语句找出结果集的单行病从中提取单个值传给主变量。
Fetch的语法:
Fetch 游标名字 into 主变量名称;
游标中包含一个指针,他将自动记录由fetch返回的下一行,最初的它设置为从查询的第一行。因此第一次执行fetch 语句时,他将检索第一航中的数据保存到变量中。在随后的每执行一个fetch 语句时,将指针移动到结果集的下一行。可以再循环中用fetch语句,这样每一次循环都会从表中读取一行数据,然后进行相同逻辑的处理。如果游标中没有剩余记录时,那么属性%found返回false,循环也就随之结束。
ü  关闭游标
关闭游标就是不能再从查询结果中检索数据。
Close 游标名称;
例如关闭上面的游标
Closeempc;

ü  完整案例
declare
cursor empc (empnop numberdefault 1)
is select * from emp where empno=empnop;//声明现实的游标
type empt is record(
empno emp.empno%type,
ename emp.ename%type,
job emp.job%type,
mgr emp.mgr%type,
hiredate emp.hiredate%type,
sal emp.sal%type,
comm emp.comm%type,
deptno emp.deptno%type );记录类型
  
empr empt;声明记录类型
begin
open empc(2);
loop
fetch empc into empr;    游标检索数据
exit when empc%notfound;
end loop;
dbms_output.put_line(empr.ename||empr.hiredate);

close empc;
end ;
注:使用select * from table 表时 其数据库中的表的结果的顺序和声明记录类型声明的顺序要相同 否则会报出如下错误

SQL> select * from emp;

EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
数据表中列的顺序
SQL> declare

  2 cursor empc (empnop number default 1)

  3  isselect * from emp where empno=empnop;

  4  typeempt is record(

  5 empno emp.empno%type,

  6 ename emp.ename%type,

  7  jobemp.job%type,

  8 hiredate emp.hiredate%type,

  9  mgremp.mgr%type,

10  salemp.sal%type,

11  commemp.comm%type,

12 deptno emp.deptno%type );

13  emprempt;

14 begin

15  openempc(2);

16  loop

17 fetch empc into empr;

18  exitwhen empc%notfound;

19  endloop;

20 dbms_output.put_line(empr.ename||empr.hiredate);

21  

22 close empc;

23  end;

24  /


declare

cursor empc (empnop numberdefault 1)

is select * from emp whereempno=empnop;

type empt is record(

empno emp.empno%type,

ename emp.ename%type,

job emp.job%type,

hiredate emp.hiredate%type,

mgr emp.mgr%type,

sal emp.sal%type,

comm emp.comm%type,

deptno emp.deptno%type );

empr empt;

begin

open empc(2);

loop

fetch empc into empr;

exit when empc%notfound;

end loop;

dbms_output.put_line(empr.ename||empr.hiredate);


close empc;

end ;


ORA-06550: 18 , 17 :

PLS-00386:发现

运维网声明 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-248979-1-1.html 上篇帖子: 如何加速Oracle大批量数据处理 下篇帖子: oracle笔记(十八)数据完整性约束
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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