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

[经验分享] oracle异常处理明细(个人简单总结)

[复制链接]

尚未签到

发表于 2016-7-24 12:57:10 | 显示全部楼层 |阅读模式
异常处理是针对系统中发生的各种错误所采取的处理措施。

PL/SQL块中的异常处理

Sql代码 DSC0000.png DSC0001.gif





  • exception
  • whenfirst_exceptionthen<handlefirstexception>
  • whensecond_exceptionthen<handlesecondexception>
  • whenothersthen<handleotherexception>



exception
when first_exception then <handle first exception>
when second_exception then <handle second exception>
when others then <handle other exception>




在异常处理中,用来获取异常代码和完整错误提示信息的两个子系统函数是sqlcode和sqlerrm。

对系统内部异常可通过sqlcode返回一个oracle错误编码号。sqlcode返回的编号除了“ora_01403没发现数据”是正值之外,其他的都是负值。

sqlerrm则返回异常代码相对应的错误信息。对用户定义的异常,sqlcode返回+1而且sqlerrm返回“用户定义异常”。如果没有异常发生,操作正常执行,则sqlcode返回0,sqlerrm返回信息“ora_0000:正常,成功完成”。



非预定义的Oracle异常

pragma exception_init(<exception_name>,<handle_code>)

在PL*SQL中,pragma exception_init告诉编译器将一个Oracle错误编号与异常名建立起来


Sql代码





  • pragmaexception_init的用法
  • declare
  • e_emp_remainingEXCEPTION;
  • pragmaexception_init(e_emp_remaining,-2292);
  • begin
  • deletefromdeptwheredeptno=10;
  • commit;
  • EXCEPTION
  • when(e_emp_remainingthen
  • dbms_output.put_line('cannotremovedept'||to_char(10)||'.employeeexist.');
  • end;



pragma exception_init的用法
declare
e_emp_remaining EXCEPTION;
pragma exception_init(e_emp_remaining ,-2292);
begin
delete from dept where deptno=10;
commit;
EXCEPTION
when (e_emp_remaining then
dbms_output.put_line('cannot remove dept'||to_char(10)||'.employee exist.');
end;



用户自定义异常

Sql代码





  • declare
  • v_enoemp.empno%type:=&.empno;
  • not_foundexception;
  • begin
  • updateempsetsal=sal*1.1whereempno=v_eno;
  • ifSQL%notfoundthen

  • raisenot_found//使用RAISE语句抛出异常

  • endif;
  • exception
  • whennot_foundthen
  • dbms_output.put_line('Youcan'tupdatethesal,thenumberdoesnot!exist!');
  • whenothersthen
  • dbms_output.put_line('otherother');
  • end



declare
v_eno emp.empno%type :=&.empno;
not_found exception;
begin
update emp set sal=sal*1.1 where  empno=v_eno;
if  SQL% notfound then
raise not_found// 使用RAISE语句抛出异常
end if;
exception
when not_found then
dbms_output.put_line('You can't update the sal,the number does not!exist!');
when others then
dbms_output.put_line('other other');
end



RAISE_APPLICATION_ERROR

可能不是很多人知道 RAISE_APPLICATION_ERROR 的用途是什么,虽然从字面上已经猜到这个函数是干什么用的。

其实 RAISE_APPLICATION_ERROR 是将应用程序专有的错误从服务器端转达到客户端应用程序。


Sql代码





  • RAISE_APPLICATION_ERROR的声明:

  • PROCEDURERAISE_APPLICATION_ERROR(error_number_inINNUMBER,error_msg_inINVARCHAR2);



  RAISE_APPLICATION_ERROR 的声明:
PROCEDURE RAISE_APPLICATION_ERROR (error_number_in IN NUMBER, error_msg_in IN VARCHAR2);

里面的错误代码和内容,都是自定义的。说明是自定义,当然就不是系统中已经命名存在的错误类别,是属于一种自定义事务错误类型,才调用此函数。

error_number_in 之容许从 -20000 到 -20999 之间,这样就不会与 ORACLE 的任何错误代码发生冲突。

error_msg_in 的长度不能超过 2K,否则截取 2K。



举个例吧:

阻止小于18岁的用户增加到数据库 employee 表中


Sql代码





  • CREATEORREPALCETRIGGERminimun_age_check
  • BEFOREINSERTONemployee
  • FOREACHROW
  • BEGIN
  • IFADD_MONTHS(:new.birth_date,18*12)>SYSDATE
  • THEN
  • RAISE_APPLICATION_ERROR(-20001,'Employeesmustatleasteighteenyearsofage.');
  • ENDIF;
  • END;



CREATE OR REPALCE TRIGGER minimun_age_check
BEFORE INSERT ON employee
FOR EACH ROW
BEGIN
IF ADD_MONTHS( :new.birth_date, 18*12) > SYSDATE
THEN
RAISE_APPLICATION_ERROR(-20001, 'Employees must at least eighteen years of age.');
END IF;
END;




在客户端,你可以写一个类似下面的程序,来测试一下。


Sql代码





  • DECLARE

  • no_babies_allowedEXCEPTION;

  • /*将名称与用于触发器中的错误号码关联起来*/
  • PRAGMAEXCEPTION_INIT(no_babies_allowed,-20001);

  • BEGIN

  • INSERTINTOemployee....;

  • EXCEPTION
  • WHENno_babies_allowed
  • THEN
  • /*
  • ||SQLERRM将传递给内置过程RAISE_APPLICATION_ERROR的消息返回
  • */
  • DBMS_OUTPUT.PUT_LINE(SQLERRM);
  • END;



DECLARE
no_babies_allowed EXCEPTION;
/*将名称与用于触发器中的错误号码关联起来*/
PRAGMA EXCEPTION_INIT(no_babies_allowed, -20001);
BEGIN
INSERT INTO employee ....;
EXCEPTION
WHEN no_babies_allowed
THEN
/*
|| SQLERRM 将传递给内置过程 RAISE_APPLICATION_ERROR 的消息返回
*/
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;



参考资料:
http://oracle.chinaitlab.com/install/355784.html

运维网声明 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-248663-1-1.html 上篇帖子: Oracle中特殊的INSERT语句--转载 下篇帖子: oracle执行计划的一些概念
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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