PL/SQL 异常

来源:互联网 发布:网络类型设置方法 编辑:程序博客网 时间:2024/06/04 20:00

-- Start

PL/SQL 异常处理和 Java 有点类似,我们可以捕获并处理异常,抛出异常,自定义异常等。下面是一个简单的例子。

DECLARENAME  VARCHAR2(10);BEGIN  SELECT 'SHANGBO' INTO NAME FROM DUAL WHERE 1 = 2;    -- 异常处理部分  EXCEPTION-- 异常处理分支一:处理 NO_DATA_FOUND 异常    WHEN NO_DATA_FOUND THEN      DBMS_OUTPUT.PUT_LINE ('NO DATA FOUND');-- 异常处理分支二:OTHERS 表示处理任何类型的异常    WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE ('UNEXPECTED ERROR');      RAISE; -- RAISE 表示向上抛出异常END;

Oracle 预定义异常

上面的例子中,NO_DATA_FOUND 是 Oracle 预定义异常,由 Oracle 自动抛出,让我们来看看 Oracle 都提供了哪些预定义异常,如下所示,我们可以根据名字很容易知道它们的意思。

Exception Name         Error CodeACCESS_INTO_NULL           -6530CASE_NOT_FOUND             -6592COLLECTION_IS_NULL         -6531CURSOR_ALREADY_OPEN        -6511DUP_VAL_ON_INDEX           -1INVALID_CURSOR             -1001INVALID_NUMBER             -1722LOGIN_DENIED               -1017NO_DATA_FOUND              +100NO_DATA_NEEDED             -6548NOT_LOGGED_ON              -1012PROGRAM_ERROR              -6501ROWTYPE_MISMATCH           -6504SELF_IS_NULL               -30625STORAGE_ERROR              -6500SUBSCRIPT_BEYOND_COUNT     -6533SUBSCRIPT_OUTSIDE_LIMIT    -6532SYS_INVALID_ROWID          -1410TIMEOUT_ON_RESOURCE        -51TOO_MANY_ROWS              -1422VALUE_ERROR                -6502ZERO_DIVIDE                -1476

Oracle 内部定义异常

Oracle 内部定义异常没有名字,只有错误代码(Error Code),如死锁(ORA-00060),它也是由 Oracle 自动抛出的,我们可以在 OTHERS 分支中捕获并处理它,通常我们不推荐这种做法。除此之外,我们还可以给内部定义异常起个名字,这样我们就可以单独处理它了,如下。

DECLARENAME  VARCHAR2(10);-- 定义异常DEADLOCK_EXCEPTION EXCEPTION;-- 关联异常和错误代码PRAGMA EXCEPTION_INIT(DEADLOCK_EXCEPTION, -60);BEGIN  SELECT 'SHANGBO' INTO NAME FROM DUAL WHERE 1 = 2;    -- 异常处理部分  EXCEPTION-- 异常处理分支一:处理 NO_DATA_FOUND 异常    WHEN NO_DATA_FOUND THEN      DBMS_OUTPUT.PUT_LINE ('NO DATA FOUND');-- 异常处理分支二:处理 DEADLOCK_EXCEPTION 异常    WHEN DEADLOCK_EXCEPTION THEN      DBMS_OUTPUT.PUT_LINE ('DEAD LOCK, TRY AGAIN LATER');-- 异常处理分支三:OTHERS 表示处理任何类型的异常    WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE ('UNEXPECTED ERROR');      RAISE; -- RAISE 表示向上抛出异常END;

自定义异常

我们还可以自定义异常,自定义异常需要我们自己抛出,下面是一个简单的例子。

DECLARENAME  VARCHAR2(10);-- 自定义异常NULL_POINT_EXCEPTION EXCEPTION;BEGIN  IF NAME IS NULL THEN    RAISE NULL_POINT_EXCEPTION; -- 抛出异常给调用者  END IF;END;

上面的例子中,我们的自定义异常没有错误代码,事实上,我们还可以给它赋一个错误代码,这个错误代码必须是整数且范围是(-20000..-20999), 如下。

DECLARENAME  VARCHAR2(10);-- 自定义异常NULL_POINT_EXCEPTION EXCEPTION;-- 给自定义异常赋错误代码PRAGMA EXCEPTION_INIT (NULL_POINT_EXCEPTION, -20000);BEGIN  IF NAME IS NULL THEN    RAISE NULL_POINT_EXCEPTION; -- 抛出异常给调用者  END IF;END;

上面的例子是比较繁琐的,有没有办法让我们可以不定义异常,在需要的时候我们又可以抛出异常呢?呵呵,答案是有,下面的例子和上面完全相同。

DECLARENAME  VARCHAR2(10);BEGIN  IF NAME IS NULL THEN    RAISE_APPLICATION_ERROR(-20000, 'name cannot null'); -- 抛出异常给调用者  END IF;END;


异常与事务

当 PL/SQL 抛出异常时,它并不会自动回滚事务,我们需要手动回滚,下面是一个简单的例子。

BEGINUPDATE EMPLOYEES SET SALARY = 9999 WHERE EMPLOYEE_ID = -1;EXCEPTION  WHEN OTHERS THEN    DBMS_OUTPUT.PUT_LINE('Error Code:' || SQLCODE || ', Error Message: ' || SQLERRM);    ROLLBACK;    RAISE;END;

--更多参见:Oracle PL/SQL 精萃

-- 声明:转载请注明出处

-- Last Edited on 2015-04-17

-- Created by ShangBo on 2015-04-16

-- End

0 0