第十二章:异常错误处理

目录

一、预定义异常

二、非预定义异常处理

三、用户自定义的异常处理

四、在PLSQL中使用SQLCODE、SQLERRM


一、预定义异常

由PL/SQL所提供的系统异常,Oracle提供了20多个预定义异常,每个预定义异常对应一个特定的Oracle错误,当PL/SQL块出现了这些Oracle错误时,会隐含地触发这些预定义异常。对于预定义异常情况的处理,无需在程序中定义,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

预定义异常列表:

错误号

异常错误信息名称

说明

ORA-00001 

DUP_VAL_ON_INDEX

试图破坏一个唯一性限制 

ORA-00051

TIMEOUT_ON_RESOURCE

在等待资源时发生超时

ORA-01001

INVALID_CURSOR 

试图使用一个无效的游标

ORA-01012 

NOT_LOGGED_ON

没有连接到ORACLE

ORA-01017

LOGIN_DENIED

无效的用户名及口令

ORA-01403 

NO_DATA_FOUND

SELECT INTO没有找到数据

ORA-01422 

TWO_MANY_ROWS

SELECT INTO 返回多行

ORA-01410

SYS_INVALID_ROWID

从字符串向ROWID转换发生错误

ORA-01476

ZERO_DIVIDE

数字值除零时触发的异常

ORA-01722

INVALID_NUMBER

转换一个数字失败

ORA-06500

STORAGE_ERROR

内存不够引发的内部错误

ORA-06501

PROGRAM_ERROR

存在PL/SQL内部问题

ORA-06502

VALUE_ERROR

转换或截断错误

ORA-06504

ROWTYPE_MISMATCH

宿主游标变量与 PL/SQL 游标变量的返回类型不兼容 

 

ORA-06511

CURSOR_ALREADY_OPEN

游标已经打开

ORA-06530 

ACCESS_INTO_NULL

未定义对象

ORA-06531

COLLECTION_IS_NULL

集合元素未初始化 

ORA-06532

SUBSCRIPT_OUTSIDE_LIMIT

使用嵌套表或 VARRAY 时,将下标指定为负数 

 

ORA-06533

SUBSCRIPT_BEYOND_COUNT

元素下标超过嵌套表或 VARRAY 的最大值 

 

ORA-06592

CASE_NOT_FOUND

CASE 中若未包含相应的 WHEN ,并且没有设置 

ORA-30625

SELF_IS_NULL

使用对象类型时,在 null 对象上调用对象方法 

--预定义异常处理
DECLARE
  v_name emp.ename%TYPE;
  v_sal  emp.sal%TYPE:=&salary;
BEGIN
  SELECT ename INTO v_name FROM emp WHERE sal = v_sal;
  DBMS_OUTPUT.put_line(v_name||'的工资是:'||v_sal);
EXCEPTION         
  WHEN NO_DATA_FOUND THEN
     DBMS_OUTPUT.put_line('没有该工资的员工');
  WHEN TOO_MANY_ROWS THEN
     DBMS_OUTPUT.put_line('多个员工具有该工资');
  WHEN OTHERS THEN
     DBMS_OUTPUT.put_line('其他异常');
END;

SELECT * FROM EMP;
--800, 一个员工
--1250   多个员工
--8000    0个员工

二、非预定义异常处理

用于处理预定义异常所不能处理的Oracle错误。此种异常需要在程序中定义。

--获取异常的错误代码和错误信息
BEGIN
    DELETE FROM DEPT WHERE deptno = &deptno;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.put_line(SQLCODE||'####'||SQLERRM);
END;


--非预定义异常的处理
DECLARE
    --1:定义非预定义异常的标识符
    e_fk EXCEPTION;
    --2:将定义好的异常与Oracle错误建立关联
    -- -2292错误代码
    PRAGMA EXCEPTION_INIT(e_fk,-2292);
BEGIN
    DELETE FROM DEPT WHERE deptno = &deptno;
EXCEPTION
    --3:捕获并处理异常
    WHEN e_fk THEN
        DBMS_OUTPUT.PUT_LINE('此部门下有员工,不能删除此部门!');
    WHEN OTHERS THEN
        DBMS_OUTPUT.put_line(SQLCODE||'####'||SQLERRM);
END;

三、用户自定义的异常处理

如果你想在某个特定事件发生时向应用程序的用户发出一些警告信息,而事件本身不会抛出Oracle内部异常,这个异常是属于引用程序的特定异常。那么就需要自定义异常。用户定义的异常错误是通过显示使用RAISE语句来触发,当引发一个异常错误时,控制就转向到EXCEPTION块异常错误部分,执行错误处理代码。

--自定义异常
DECLARE
  v_empno emp.empno%TYPE:=&empno;
  --1:定义异常
  e_no_result EXCEPTION;
BEGIN
  UPDATE emp SET sal = sal + 100 WHERE empno = v_empno;
  IF SQL%NOTFOUND THEN
	--2:指定触发异常的时机
    RAISE e_no_result;
  ELSE
    COMMIT;
  END IF;
EXCEPTION
    --3:捕捉并处理异常
  WHEN e_no_result THEN
    DBMS_OUTPUT.put_line('数据更新失败!');
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('其他错误');
END;

四、在PLSQL中使用SQLCODE、SQLERRM

异常处理函数:

  • 异常处理函数用于取得Oracle错误号和错误信息,其中函数SQLCODE用于取得错误号,SQLERRM用于取得错误信息。
  • 当编写PL/SQL块时,通过在异常处理部分引用函数SQLCODE和SQLERRM,可以取得未预计到的Oracle错误。
  • 通过使用内置过程RAISE_APPLICATION_ERROR,可以在建立子程序(过程、函数、包)时自定义错误号和错误信息。
--异常处理函数SQLCODE和SQLERRM的使用
DECLARE
  v_empno emp.empno%TYPE:= &empno;
  v_ename emp.ename%TYPE:= '&ename';
  v_deptno emp.deptno%TYPE:= &deptno;
BEGIN
  INSERT INTO emp(empno,ename,deptno)VALUES(v_empno,v_ename,v_deptno);
  IF SQL%FOUND THEN
    DBMS_OUTPUT.put_line('数据插入成功!');
    COMMIT;
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line('错误号:'||SQLCODE);
    DBMS_OUTPUT.put_line('错误信息:'||SQLERRM);
END;   
发布了26 篇原创文章 · 获赞 27 · 访问量 5459

猜你喜欢

转载自blog.csdn.net/weixin_44337241/article/details/104783875