热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

快速掌握Oracle异常

自定义例外是指由PLSQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。看一看以下PLSQL块的运行。decla

自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。 看一看以下PL/SQL块的运行。 decla

自定义例外是指由PL/SQL开发人员所定义的例外。预定义例外和非预定义例外都和Oracle错误有关,并且出现Oracle错误时会隐含的处罚相应例外;而自定义例外与Oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外。

看一看以下PL/SQL块的运行。

declare
    e_integrity exception;
   pragma exception_init(e_integrity,-2291);
begin
    update emp set deptno=&dno where empno=&eno;
exception  
      when e_integrity  then 
         dbms_output.put_line('该部门不存在');  
 end;         
     

使用例外函数:

1、SQLCODE 和SQLERRM

SQLCODE用于返回Oracle错误号,而SQLERRM则用于返回错误号所对应的错误消息。为了在PL/SQL应用程序中处理其他未预料到的Oracle错误,用户可以在例外处理部分的WHEN OTHERS 子句后引用这两个函数,以取得相关的Oracle错误.示例如下:

DECLARE 
     v_ename emp.ename%type;
BEGIN
     SELECT ename INTO v_ename 
             FROM emp 
      WHERE sal=&v_sal;    
   dbms_output.put_line('雇员名:'||v_ename);  
EXCEPTION 
    WHEN NO_DATA_FOUND THEN
       dbms_output.put_line('不存在工资为'||&v_sal||'的雇员');  
    WHEN OTHERS  THEN
       dbms_output.put_line('错误号:'||SQLCODE); 
       dbms_output.put_line(SQLERRM);  
 END;      
 

当输入v_sal:1250时。

错误号:-1422
ORA-01422: 实际返回的行数超出请求的行数


2. RAISE_APPLICATION_ERROR

该函数用于在PL/SQL应用程序中自定义错误消息。注意该过程只能在数据端的子过程(过程、函数、包、触发器)中使用,而不能在匿名块和客户端的子程序中使用,使用该函数的语法如下:

raise_application_error(error_number,message[ , {TRUE| FALSE}]);

其中,error_number用于定义错误号,该错误号必须是在-20000至-20999之间的负整数;message用于指定错误消息,并且该消息的长度不能超过2048字节;第三个参数为可选参数,如果设置为TURE,则该错误会放在先前错误的堆栈中;如果设置为FALSE(默认值),则会替换先前所有的错误。使用该过程的示例如下:

CREATE OR REPLACE PROCEDURE raise_comm
    (eno number,
      commission number
    )
IS
    v_comm  emp.comm%TYPE;  
    
BEGIN
    SELECT comm INTO v_comm 
         FROM emp  
      WHERE empno=eno; 
  IF v_comm IS NULL THEN
      RAISE_APPLICATION_ERROR(-20021,'该雇员无补助啊',TRUE);  
  END IF;
EXCEPTION 
     WHEN NO_DATA_FOUND THEN 
       dbms_output.put_line('该雇员不存在');      
END;   


call raise_comm(7900,100);

显示如下错误:

ORA-20021: 该雇员无补助啊
ORA-06512: 在 "SCOTT.RAISE_COMM", line 13

上面出现的错误,会在异常栈中打印出来。

下面是本人认为比较不错的异常处理方式:

一般情况下,我们会把异常名和异常号进行绑定,可能就是你所想要的结果吧

DECLARE
    vnumber NUMBER(4);
    biger EXCEPTION;           --异常名
    PRAGMA EXCEPTION_INIT(biger,-20001); --异常名和异常号绑定
    equal EXCEPTION;
    PRAGMA EXCEPTION_INIT(equal,-20002);
    small EXCEPTION;
    PRAGMA EXCEPTION_INIT(small,-20003);
BEGIN
    vnumber:=&vnumber;
    IF vnumber >10 THEN
       RAISE_APPLICATION_ERROR(-20001,'哈哈,大于10啊');
    ELSIF vnumber = 10 THEN
       RAISE_APPLICATION_ERROR(-20002,'嗯,等于10...');
   ELSIF vnumber <10 THEN
       RAISE_APPLICATION_ERROR(-20003,'哦,小于10啊');
    END IF;
EXCEPTION
     WHEN biger THEN
      dbms_output.put_line('哈哈,大于10啊');
     WHEN equal THEN
       dbms_output.put_line('嗯,等于10...');
     WHEN small THEN
       dbms_output.put_line('哦,小于10啊');
END;

除了上面自定义的异常,我们还可以采用下面的这种方式定义异常

 CREATE OR REPLACE PROCEDURE pro_emp
 (
   --- 多个用逗号隔开
   v_eno IN NUMBER 
 )
 IS
 --------多个用分号隔开
    v_max_id NUMBER;
    v_ename VARCHAR2(10);
    v_raise EXCEPTION;  ---------定义一个异常
BEGIN 
      SELECT max(a.empno) into v_max_id  from emp a;  
      IF v_eno >v_max_id  THEN 
           RAISE v_raise;               ---遇到例外,执行这个异常,退出程序 进入到Exception部分
      END IF;
      SELECT ename into v_ename from emp where empno=v_eno;
      dbms_output.put_line('员工名称为:'||v_ename);     
EXCEPTION 
     WHEN v_raise THEN                                ---------捕获v_raise异常
            dbms_output.put_line('V_ENO大于最大员工号');
        /*  RAISE_APPLICATION_ERROR(-20000,'v_id not exists');    */
     WHEN NO_DATA_FOUND THEN
        /* RAISE_APPLICATION_ERROR(-20011,'ERROR:不存在');*/
          dbms_output.put_line('没有获得有效数据');       
END;

推荐阅读
  • 在数据分析工作中,我们通常会遇到这样的问题,一个业务部门由若干业务组构成,需要筛选出每个业务组里业绩前N名的业务员。这其实是一个分组排序的 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了通过mysql命令查看mysql的安装路径的方法,提供了相应的sql语句,并希望对读者有参考价值。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
author-avatar
暂时不用的微博
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有