`

oracle之异常学习

阅读更多
ORACLE异常包括预定义异常,非预定义异常,自定义异常。
1、预定义异常
即oracle已定义的异常,无需在程序中定义,由ORACLE自动将其引发,可以直接使用定义的异常名称捕获。ORACLE预定义的异常情况大约有24个,如下。
错误号      异常错误信息名称          异常产生原因
ORA-0001    dup_val_on_index          违反了唯一性限制
ORA-0051    timeout_on_resource       在等待资源时发生超时
ORA-0061    transaction_backed_out    由于发生死锁事务被撤消
ORA-1001    invalid_cursor            试图使用一个无效的游标
ORA-1012    not_logged_on             没有连接到ORACLE
ORA-1017    login_denied              无效的用户名/口令
ORA-1403    no_data_found             SELECT INTO没有找到数据
ORA-1410    sys_invalid_id            无效的 rowid 字符串
ORA-1422    too_many_rows             SELECT INTO 返回多行
ORA-1476    zero_divide               除数为 0
ORA-1722    invalid_number            转换一个数字失败
ORA-6500    storage_error             内存不够引发的内部错误
ORA-6501    program_error             内部错误
ORA-6502    value_error               转换或截断错误(赋值时,变量长度不足以容纳实际数据)
ORA-6504    rowtype_mismatch          主游标变量与 PL/SQL变量有不兼容行类型
ORA-6511    curser_already_open       试图打开一个已处于打开状态的游标
ORA-6530    access_into_null          试图为null 对象的属性赋值
ORA-6531    collection_is_null        集合元素未初始化
ORA-6532    subscript_outside_limit   对嵌套或varray索引得引用超出声明范围以外
ORA-6533    subscript_beyond_count  对嵌套或varray 索引得引用大于集合中元素的个数.
ORA-6592    case_not_found          case中若未包含相应的when,并且没有设置.
            self_is_null            使用对象类型时,在 null 对象上调用对象方法


预定义异常可以通过异常名捕获处理,示例如下(所有示例以PLSQL执行):
declare
cc varchar2(1000);
nn number := 0;
begin
    select t.label_value into cc from mem_users_label t where t.user_id = '111';
    dbms_output.put_line('data found');
    EXCEPTION
    WHEN no_data_found THEN
      dbms_output.put_line('no data found');
end;

PLSQL执行结果为:
no data found


2、非预定义异常
即其他标准的ORACLE错误,但是oracle并没有对其进行定义。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。
创建测试表
create table ZL_TEST1
(
  id         VARCHAR2(10) not null,
  name       VARCHAR2(10),
  age        VARCHAR2(50),
  primary key(id)
);

create table ZL_TEST2
(
  id         VARCHAR2(10),
  name       VARCHAR2(30),
  age        NUMBER
);
alter table ZL_TEST2 add constraint PRI_FOREIGNID foreign key (ID)
  references ZL_TEST1 (ID);

插入测试数据
insert into zl_test1 values(1,'aa',12);
insert into zl_test1 values(2,'ab',12);
insert into zl_test1 values(3,'ac',12);

测试代码
declare
deptno_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT(deptno_remaining, -2292);
begin
  delete from zl_test1 where id='1';
  EXCEPTION
    WHEN deptno_remaining THEN
      dbms_output.put_line('sqlcode is:'||SQLCODE||',error messesge is:'||SQLERRM);   
end;

3、自定义异常
需要根据实际情况自己定义错误消息,RAISE_APPLICATION_ERROR用于自定义错误消息,并且消息号必须在-20000~-20999之间,以便与oracle定义的错误区分开。用户定义的异常错误可以通过显式使用RAISE语句来触发,也可以通过RAISE_APPLICATION_ERROR定义。当引发一个异常错误时,控制就转向到 EXCEPTION块异常错误部分,执行错误处理代码。
RAISE触发异常:
DECLARE
   no_result  EXCEPTION;
BEGIN
   UPDATE zl_test1 SET name = 'test' WHERE id = 8;
   IF SQL%NOTFOUND THEN
      RAISE no_result;
   END IF;
   EXCEPTION
   WHEN no_result THEN 
      DBMS_OUTPUT.PUT_LINE('你的数据更新语句失败了!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;


RAISE_APPLICATION_ERROR定义异常
RAISE_APPLICATION_ERROR由oracle的DBMS_STANDARD包提供,语法如下:
RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] );

    error_number 是从 –20,000 到 –20,999 之间的参数,
    error_message 是相应的提示信息(< 2048 字节),
    keep_errors 为可选,如果keep_errors =TRUE ,则新错误将被添加到已经引发的错误列表中。如果keep_errors=FALSE(缺省),则新错误将替换当前的错误列表。
示例:
创建表:
CREATE TABLE errlog(
  Errcode NUMBER,
  Errtext CHAR(40));

创建函数:
CREATE OR REPLACE FUNCTION get_salary(p_deptno NUMBER)
RETURN NUMBER 
AS
  v_sal NUMBER;
BEGIN
  IF p_deptno IS NULL THEN
    RAISE_APPLICATION_ERROR(-20991, ’部门代码为空’);
  ELSIF p_deptno<0 THEN
    RAISE_APPLICATION_ERROR(-20992, ’无效的部门代码’);
  ELSE
    SELECT SUM(employees.salary) INTO v_sal FROM employees 
    WHERE employees.department_id=p_deptno;
    RETURN v_sal;
  END IF;
END;

测试:
DECLARE 
  V_salary NUMBER(7,2);
  V_sqlcode NUMBER;
  V_sqlerr VARCHAR2(512);
  Null_deptno EXCEPTION;
  Invalid_deptno EXCEPTION;
  PRAGMA EXCEPTION_INIT(null_deptno,-20991);
  PRAGMA EXCEPTION_INIT(invalid_deptno, -20992);
BEGIN
  V_salary :=get_salary(10);
  DBMS_OUTPUT.PUT_LINE('10号部门工资:' || TO_CHAR(V_salary));

  BEGIN
    V_salary :=get_salary(-10);
  EXCEPTION
    WHEN invalid_deptno THEN
      V_sqlcode :=SQLCODE;
      V_sqlerr  :=SQLERRM;
      INSERT INTO errlog(errcode, errtext) 
      VALUES(v_sqlcode, v_sqlerr);
      COMMIT;
  END inner1;

  V_salary :=get_salary(20);
  DBMS_OUTPUT.PUT_LINE('部门号为20的工资为:'||TO_CHAR(V_salary));

  BEGIN
    V_salary :=get_salary(NULL);
  END inner2;

  V_salary := get_salary(30);
  DBMS_OUTPUT.PUT_LINE('部门号为30的工资为:'||TO_CHAR(V_salary));

  EXCEPTION
    WHEN null_deptno THEN
      V_sqlcode :=SQLCODE;
      V_sqlerr  :=SQLERRM;
      INSERT INTO errlog(errcode, errtext) VALUES(v_sqlcode, v_sqlerr);
      COMMIT;
    WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END outer;


4、总结
EXCEPTION必须放在begin/end代码块中:如上面的示例,inner1的代码块中包含exception,捕获到invalid_deptno异常并处理后继续执行,get_salary(20)正常执行,inner2代码块中并没有exception捕获异常,故此代码块终止,调到其父代码块,异常被最后的exception捕获,inner2到最后的exception中的sql不会被执行,即get_salary(30)不会被执行。
如果循环中需要捕获异常,需要在可能存在异常的sql处添加begin/end,组成sql块;或者将exception放在循环外面,此时当某次循环中出现异常时整个循环终止,异常被exception捕获。
declare
cursor mycur is select * from mem_agingtype_labinf_syncbak where rownum<10;
c_row mycur%rowtype;
cc varchar2(1000);
nn number := 0;
begin
  for c_row in mycur loop
    nn := nn+1;
    begin
    select t.label_value into cc from mem_users_label t where t.user_id = c_row.user_id;
    EXCEPTION
    WHEN no_data_found THEN
      dbms_output.put_line('no data found');
    end;
    dbms_output.put_line(nn);
  end loop;
  dbms_output.put_line('end loop');
end;
分享到:
评论

相关推荐

    oracle存储过程学习经典入门

    Oracle 存储过程学习经典入门 Oracle 存储过程学习目录是 Oracle 存储过程学习的基础知识,了解 Oracle 存储过程的基本语法、基础知识和一些常见问题的解决方法是非常重要的。本文将从 Oracle 存储过程的基础知识...

    ORACLE异常处理剖析.pdf

    Oracle异常处理是数据库管理和应用程序开发中的关键环节,它涉及到对程序执行过程中可能出现的错误和异常...在日常工作中,应重视错误和异常的处理,通过持续学习和实践,不断提高对Oracle异常处理的理解和应用能力。

    oracle学习视屏

    Oracle数据库是全球最广泛使用的商业关系型数据库管理系统之一,它以其高效、稳定和强大的功能而闻名。"Oracle学习视屏"是一系列针对Oracle数据库的学习资源,涵盖了从基础到进阶的全面教程,适合对数据库技术感兴趣...

    ORACLE存储过程学习源码

    这个"ORACLE存储过程学习源码"集合包含了从基础到高级的30个示例,是学习和掌握Oracle存储过程的理想资源。下面,我们将深入探讨存储过程的基本概念、结构、类型,以及如何通过这些源码进行学习。 1. **存储过程的...

    oracle存储过程学习经典

    综上所述,Oracle存储过程的学习不仅涉及基础语法和结构的理解,还需要掌握其高级特性和最佳实践,包括动态SQL、异常处理、性能优化以及与其他编程语言的集成。通过深入研究这些知识点,可以充分发挥Oracle存储过程...

    oracle学习实用脚本

    Oracle学习实用脚本集合是一份宝贵的资源,专为想要深入理解和掌握Oracle数据库技术的人们准备。这份资料由一位经验丰富的数据库老师精心编写,旨在通过实际的示例脚本来帮助学习者快速上手并精通Oracle的关键技术。...

    Oracle数据库学习课件

    课程会教授PL/SQL的语法结构、流程控制语句、异常处理,以及如何在Oracle环境中使用它进行业务逻辑处理。 4. **Oracle数据库管理**:这部分内容可能涵盖数据库实例管理、表空间和数据文件的管理、用户和权限管理、...

    Oracle 10g 学习课件

    Oracle 10g 学习课件是一套全面的教程,专为想要深入理解Oracle数据库管理系统的人们设计。Oracle数据库是全球广泛使用的大型企业级数据库系统,尤其在金融、电信和政府等行业中占据主导地位。Oracle 10g是其第十个...

    Oracle视频学习

    5. **PL/SQL编程**:PL/SQL是Oracle特有的过程化语言,学习编写存储过程、函数、触发器和游标,掌握异常处理和事务控制。 6. **索引和性能优化**:了解索引的类型(B树、位图、唯一性索引等),如何创建和使用索引...

    Oracle学习资料大全

    通过"plsql语法帮助",学习者可以深入理解PL/SQL的语法结构,包括变量声明、条件语句(如IF-THEN-ELSIF)、循环(WHILE, FOR)、异常处理(BEGIN-EXCEPTION-END)以及游标等核心概念。 "04_管理数据库口令文件.pdf...

    oracle学习资料集

    Oracle是全球广泛使用的数据库管理系统,尤其在企业级应用中占据主导地位。这个“Oracle学习资料集”包含了多种资源,帮助用户深入理解Oracle的核心概念、管理和...希望这些资料能为你的Oracle学习之路提供有力支持。

    oracle数据库整体学习资料

    这个"Oracle数据库整体学习资料"压缩包包含了多个PPT和文档,旨在为学习者提供一个全面了解和掌握Oracle数据库的资源集合。 首先,我们从`Oracle体系结构简介.ppt`开始,这个文件会详细介绍Oracle数据库的核心组成...

    Oracle数据库学习指南

    15.PLSQL异常处理初步 16.SQL语句性能调整原则 17.创建和使用分区的表 18.基于成本的优化器一般错误概念和问题 19.Delphi 3_0中连接数据库的三种方式 20.远程数据库的访问 21.监控数据库性能的SQL 22...

    Oracle自主学习核心资料

    这份"Oracle自主学习核心资料"涵盖了Oracle学习的关键领域,旨在帮助用户深入理解Oracle数据库的各个方面,提升数据库管理技能。 首先,我们要关注的是"关系数据库与SQL语言环境"。SQL(Structured Query Language...

    oracle数据库管理大家学习一下

    Oracle数据库管理系统是全球广泛使用的大型关系型数据库系统之一,尤其在企业级应用中占据着重要地位。Oracle数据库管理涉及的内容非常广泛,包括数据库设计、安装配置、性能优化、备份恢复、安全控制等多个方面。...

    oracle学习练习实验

    Oracle数据库是全球广泛使用的大型关系型数据库管理系统,尤其在企业级应用中占据重要地位。对于初学者来说,Oracle的学习是一个逐步深入的过程,涉及到SQL语言、数据库管理、表...祝你在Oracle的学习之旅中取得成功!

    oracle 过程和包学习

    在学习Oracle过程和包时,你需要理解以下几个核心概念: 1. **声明部分**:在过程或包中声明变量、常量和游标,用于存储数据或控制流程。 2. **控制结构**:包括条件语句(IF-THEN-ELSIF-ELSE)、循环(FOR、WHILE、...

Global site tag (gtag.js) - Google Analytics