现在的位置: 首页 > 综合 > 正文

Oracle异常处理

2013年08月12日 ⁄ 综合 ⁄ 共 4190字 ⁄ 字号 评论关闭
为了提高应用程序的健壮性,开发人员必须考虑程序可能出现的各种错误,并进行相应的处理.

Oracle中异常分为预定义例外,非预定义例外和自定义例外三种.

## 处理预定义异常

预定义异常是指由PL/SQL所提供的系统异常.PL/SQL应用程序违反了Oralce规则或系统限制时,则会隐含的触发一个内部异常.

# PL/SQL为开发人员提供了二十多个预定义异常:

 

1.ACCESS_INTO_NULL

该异常对应于ORA-06530错误.当开发对象类型应用时,如果没有初始化对象,直接为对象属性赋值,该异常触发.

DECLARE

  emp emp_type;

BEGIN

  emp.name := 'SCOTT';

EXCEPTION

  WHEN ACCESS_INTO_NULL THEN

    DBMS_OUTPUT.PUT_LINE('首先初始化对象emp');

END;

/

2.CASE_NOT_FOUND

对应于ORA-06592错误.CASE语句时,如果WHEN子句没有包含必须的条件分支,并且没有仓含ELSE子句,被触发.

DECLARE

  v_sal emp.sal%TYPE;

BEGIN

  SELECT sal INTO v_sal FROM emp WHERE empno = &&no;

  CASE

    WHEN v_sal ? 1000 THEN

      UPDATE emp SET sal = sal + 100 WHERE empno = &no;

    WHEN v_sal ? 2000 THEN

      UPDATE emp SET sal = sal + 150 WHERE empno = &no;

    WHEN v_sal ? 3000 THEN

      UPDATE emp SET sal = sal + 200 WHERE empno = &no;

  END CASE;

EXCEPTION

  WHEN CASE_NOT_FOUND THEN

    DBMS_OUTPUT.PUT_LINE('CASE语句中没有与' || v_sal || '相关的条件.');

END;

/

3.COLLECTION_IS_NULL

对应于ORA-06531错误.在给集合元素(嵌套表或VARRAY类型)赋值前,必须首先寝化集合元素.否则触发该异常.

DECLARE

  TYPE ename_table_type IS TABLE OF emp.ename%TYPE;

  ename_table ename_table_type;

BEGIN

  SELECT ename INTO ename_table(2) FROM emp WHERE empno = &no;

  DBMS_OUTPUT.PUT_LINE('雇员名: ' || ename_table(2));

EXCEPTION

  WHEN COLLECTION_IS_NULL THEN

    DBMS_OUTPUT.PUT_LINE('必须初始化集合元素.');

END;

/

4.CURSOR_ALREADY_OPEN

对应于ORA-06511错误.当重新打开已经打开的游标时,会隐含地触发该异常.

DECLARE

  CURSOR emp_cursor IS

    SELECT ename, sal FROM emp;

BEGIN

  OPEN emp_cursor;

  FOR emp_record IN emp_cursor LOOP

    DBMS_OUTPUT.PUT_LINE(emp_record.ename);

  END LOOP;

EXCEPTION

  WHEN CURSOR_ALREADY_OPEN THEN

    DBMS_OUTPUT.PUT_LINE('游标已经打开.');

END;

/

5.DUP_VAL_ON_INDEX

对应于ORA-00001错误,当在惟一索引所对应的列上键入重复值时触发.

BEGIN

  UPDATE dept SET deptno = &new_no WHERE deptno = &old_no;

EXCEPTION

  WHEN DUP_VAL_ON_INDEX THEN

    DBMS_OUTPUT.PUT_LINE('deptno列上不能出现重复值.');

END;

/

6.INVALID_CURSOR

对应于ORA-01001错误.当试图在不合法的游标上执行操作时触发.如从未打开的游标取数据,关闭未打开的游标等.

DECLARE

  CURSOR emp_cursor IS

    SELECT ename, sal FROM emp;

  emp_record emp_cursor%ROWTYPE;

BEGIN

  FETCH emp_cursor

    INTO emp_record;

  CLOSE emp_cursor;

EXCEPTION

  WHEN INVALID_CURSOR THEN

    DBMS_OUTPUT.PUT_LINE('请检查游标是否已经打开.');

END;

/

7.INVALID_NUMBER

对应于ORA-01722错误.当内嵌SQL语句不能有效地将字符转变成数字时触发.如数值100被写成"1oo".

BEGIN

  UPDATE emp SET sal = sal + '100';

EXCEPTION

  WHEN INVALID_NUMBER THEN

    DBMS_OUTPUT.PUT_LINE('输入的数字不正确.');

END;

/

8.NO_DATA_FOUND

对应于ORA-01403错误.当执行SELECT INOT未返回行,或引用了索引表未初始化元素时触发.

DECLARE

  v_sal emp.sal%TYPE;

BEGIN

  SELECT sal INTO v_sal FROM emp WHERE lower(ename) = lower('&name');

EXCEPTION

  WHEN NO_DATA_FOUND THEN

    DBMS_OUTPUT.PUT_LINE('不存在该雇员.');

END;

/

9.TOO_MANY_ROWS

对应于ORA-01422错误,当执行SELECT INTO语句时,如果返回超过一行触发该异常.

DECLARE

  v_ename emp.ename%TYPE;

BEGIN

  SELECT ename INTO v_ename FROM emp WHERE sal = &sal;

EXCEPTION

  WHEN TOO_MANY_ROWS THEN

    DBMS_OUTPUT.PUT_LINE('返回多行.');

END;

/

10.ZERO_DIVIDE

对应于ORA-01476错误.当运行PL/SQL块时,如果使用数据值除0触发该异常.

DECLARE

  num1 INT := 100;

  num2 INT := 0;

  num3 NUMBER(6, 2);

BEGIN

  num2 := num1 / num2;

EXCEPTION

  WHEN ZERO_DIVIDE THEN

    DBMS_OUTPUT.PUT_LINE('分母不能为0.');

END;

/

11.SUBSCRIPT_BEYOND_COUNT

对应于ORA-06533错误.当使用嵌套表或VARRAY元素时,如果下标越界触发该异常.

DECLARE

  TYPE emp_array_type IS VARRAY(20) OF VARCHAR2(10);

  emp_array emp_array_type;

BEGIN

  emp_array := emp_array_type('SCOTT', 'MARY');

  DBMS_OUTPUT.PUT_LINE(emp_array(3));

EXCEPTION

  WHEN SUBSCRIPT_BEYOND_COUNT THEN

    DBMS_OUTPUT.PUT_LINE('下标越界.');

END;

/

12.SUBSCRIPT_OUTSIDE_LIMIT

对应于ORA-06532错误.当使用嵌套表或VARRAY元素时,如果下标为负值触发该异常.

DECLARE

  TYPE emp_array_type IS varray(20) OF VARCHAR2(10);

  emp_array emp_array_type;

BEGIN

  emp_array := emp_array_type('SCOTT', 'MARY');

  DBMS_OUTPUT.PUT_LINE(emp_array(-1));

EXCEPTION

  WHEN SUBSCRIPT_OUTSIDE_LIMIT THEN

    DBMS_OUTPUT.PUT_LINE('下标不能是负数.');

END;

/

13. VALUE_ERROR

对应于ORA-06502错误.当在PL/SQL块中执行赋值操作时,如果变量长度不足则触发该异常.

DECLARE

  v_ename VARCHAR2(5);

BEGIN

  SELECT ename INTO v_ename FROM emp WHERE empno = &no;

  DBMS_OUTPUT.PUT_LINE(v_ename);

EXCEPTION

  WHEN VALUE_ERROR THEN

    DBMS_OUTPUT.PUT_LINE('变量长度不够.');

END;

/

## 其它预定义异常

 

1.LONIN_DENIED

对应于ORA-01017错误.PL/SQL应用程序要连接Oracle数据库时,如果密码错误则触发该异常.

2.NOT_LOGGED_ON

对应于ORA-01012错误.如果程序没连接Oracle数据库,那么执行PL/SQL访问数据库时触发该异常.

3.PROGRAM_ERROR

对应于ORA-06501.如果出现该错误,则表示PL/SQL内部问题,用户可能需要重新安装数据字典和PL/SQL系统包.

4.ROWTYPE MISMATCH

对应于ORA-06504错误.赋值时,宿主游标变量和PL/SQL游标变量的返回类型不兼容时触发该异常.

5.SELF_IF_NULL

对应于ORA-30625.当使用对象类型时,如果在NULL实例上调用成员方法则触发该异常.

6.STORAGE_ERROR

对应于ORA-06500错误.PL/SQL块运行时,如果走出内在空间或内在被损坏则触发该异常.

7.SYS_INVALID_ROWID

对应于ORA-01410错误.当将字符串转变为ROWID,如果使用了无效的字符串则触发该异常.

8.TIMEOUT_ON_RESOURCE

对应于ORA-00051错误.Oracle在等待资源超出现超时错误时触发该异常.

## 非预定义异常

使用预定义异常,只能处理21Oracle错误.而当使用PL/SQL开发应用程序时,

抱歉!评论已关闭.