您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > oracle异常和游标管理
1异常和游标管理第七章2目标详细讨论异常游标管理技巧3异常8-1程序错误编译时运行时异常处理运行时错误4PL/SQL是如何处理异常的?错误引发异常每当引发异常时,都将控制权传递给异常处理程序异常处理程序处理异常异常8-25异常中涉及的步骤•声明异常•引发异常•处理异常•Declare•Begin•Exception•End;异常8-36异常的类型•预定义的异常•非预定义的异常•用户定义的异常异常8-47预定义的异常•由Oracle为常见错误预定义•在DBMS_STANDARD程序包中提供了这些定义•不需要显式声明预定义的异常8预定义的异常declarevar_statusorder_master.ostatus%type;beginselectostatusintovar_statusfromorder_master;dbms_output.put_line(var_status);--exception--whentoo_many_rowsthen--dbms_output.put_line('查询返回不止一行');end;在Oracle中无法从引发异常的位置继续处理。9预定义的异常exceptionwhen…thenwhen…thenwhenothersthenend;预定义异常列表:参考课本page17010非预定义的异常•指定与Oracle错误关联的异常•关联是通过PRAGMAEXCEPTION_INIT编译指示建立的•PRAGMAEXCEPTION_INIT通知编译器使异常名称与标准的oracle服务器错误编号关联。非预定义的异常11非预定义的异常declaredup_rowexception;pragmaexception_init(dup_row,-1422);var_statusorder_master.ostatus%type;beginselectostatusintovar_statusfromorder_master;dbms_output.put_line(var_status);exceptionwhendup_rowthendbms_output.put_line('返回行数超过一行');end;12用户定义的异常•由程序定义的错误•在声明部分中声明•类型EXCEPTION声明用户定义的异常•是使用RAISE语句显式引发的用户定义的异常13用户定义的异常参考课本举例page173.14Raise_Application_Error•创建用户定义的错误消息,用户定义的错误消息可以比指定的异常描述的更详细。•既可以在可执行部分中使用,也可以在异常部分中使用•错误编号必须介于–20000和–20999之间•错误消息的长度可长达2048个字节定义错误消息15定义错误消息declaredup_rowexception;pragmaexception_init(dup_row,-1422);var_statusorder_master.ostatus%type;beginselectostatusintovar_statusfromorder_master;dbms_output.put_line(var_status);exceptionwhendup_rowthenraise_application_error(-20001,'返回行数超过一行',true);end;16游标游标•指向上下文区域的句柄或指针•上下文区域-用于SQL处理的内存区•上下文区域的内容–语句处理的行数–指向语句的语法分析表示的指针17游标类型游标类型•静态游标–隐式游标–显式游标•REF游标18隐式游标隐式游标PL/SQL为所有DML将打开一个隐式游标,在SQL操作完成后,关闭游标。19游标属性•%NOTFOUND:true表示DML语句不返回任何行。•%FOUND:true表示DML语句影响一行或者多行。•%ROWCOUNT:统计DML语句返回的行数。•%ISOPEN:在DML语句执行之后,始终为false。隐式游标20隐式游标begindeletefromorder_masterwhereorderno='o201';ifsql%notfoundthendbms_output.put_line('未找到值');elsedbms_output.put_line('找到并删除之');endif;end;21隐式游标declareorder_noorder_master.orderno%type;beginselectordernointoorder_nofromorder_masterwhereorderno='o001';ifsql%rowcount0thendbms_output.put_line(sql%rowcount);dbms_output.put_line('从中选择行');elsedbms_output.put_line('从中未选择行');endif;end;22显式游标•由用户显式声明•游标将指向活动集中的当前行控制显式游标Open:执行查询,并将游标指针置于第一行。Fetch:游标指针前进到下一行。Close:关闭游标。显式游标23显式游标declareicodeorder_detail.itemcode%type;cursoraisselectitemcodefromorder_detailwhereorderno='o001';beginopena;loopfetchaintoicode;updateitemfilesetitemrate=22.5whereitemcode=icode;exitwhena%notfound;endloop;dbms_output.put_line('项费率已经更新');closea;end;24显式游标declareorder_noorder_detail.orderno%type;cursoraisselectordernofromorder_detailwhereitemcode='i205';beginopena;loopfetchaintoorder_no;updateorder_mastersetostatus='D'whereorderno=order_no;exitwhena%notfound;endloop;closea;end;25显式游标declarecursortestisselect*fromorder_detailwhereorderno='o001';myorderorder_detail%rowtype;--声明游标beginopentest;--打开游标loopfetchtestintomyorder;--操作游标exitwhentest%notfound;endloop;dbms_output.put_line('从表中获取的行数为:'||test%rowcount);closetest;--关闭游标end;26显式游标declarecursormycurisselect*fromorder_master;beginifnotmycur%isopenthendbms_output.put_line('游标尚未被打开');endif;openmycur;ifmycur%isopenthendbms_output.put_line('游标已经打开');endif;closemycur;end;27查询嵌套表中数据的游标举例28循环游标显式游标的替代方法它的工作原理是什么?隐式打开游标自动从活动集获取行在处理完所有行时关闭游标优点•简化代码的编写循环游标29循环游标--使用循环游标删除特定供应商的所有订单declarecursorfor_curisselectordernofromorder_masterwherevencode='v002';beginforcust_recinfor_curloopdeletefromorder_detailwhereorderno=cust_rec.orderno;endloop;dbms_output.put_line('供应商v002的所有订单被取消');commit;end;30•游标变量类似于PL/SQL变量,可以在运行时接纳不同的值。•定义游标变量类型的语法typetype_nameisrefcursorreturnreturn_type;•声明游标变量ref_vartype;REF游标31游标变量强游标(有约束)、弱游标(无约束)当声明的游标变量类型有返回类型的时候,称为强游标。没有返回类型的游标变量称为弱游标。Typet_add_refisrefcursorreturnvendor_master%rowtype;Typet_add_refisrefcursor;32使用游标变量•在运行时使不同的语句与之关联•Opencursor_variableforselect_statement;33游标变量举例declaretyper1_curisrefcursor;var1r1_cur;onovarchar2(5);novarchar2(20);qordnumber;beginno:='gf';ifupper(no)='ORDERNO'thenopenvar1forselectordernofromorder_masterwherevencode='v001';fetchvar1intoono;dbms_output.put_line('订单号'||ono);closevar1;elseopenvar1forselectqty_ordfromorder_detailwhereorderno='o001';loopfetchvar1intoqord;exitwhenvar1%notfound;dbms_output.put_line('订购数量是'||qord);endloop;closevar1;endif;end;34游标变量举例declaretypeordertypeisrecord(ordernovarchar2(5),odatedate,vencodevarchar2(5),ostatuschar(1),del_datedate);typeordercurisrefcursorreturnorder_master%rowtype;order_cvordercur;order_recordertype;beginopenorder_cvforselectorderno,odate,vencode,ostatus,del_datefromorder_masterwherevencode='v001';loopfetchorder_cvintoorder_rec;exitwhenorder_cv%notfound;dbms_output.put_line('这些值为:'||order_rec.orderno||''||order_rec.odate||''||order_rec.vencode||''||order_rec.ostatus||''||order_rec.del_date);endloop;closeorder_cv;end;35限制•不能在程序包中声明游标变量•远程子程序不能接受游标变量的值•不能使用比较操作符对游标变量进行相等或不相等测试•不能将空值赋予游标变量•表不能存储游标变量的值游标管理9-9
本文标题:oracle异常和游标管理
链接地址:https://www.777doc.com/doc-11934 .html