-- Start
PL/SQL 异常处理和 Java 有点类似,我们可以捕获并处理异常,抛出异常,自定义异常等。下面是一个简单的例子。
DECLARE NAME 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;
上面的例子中,NO_DATA_FOUND 是 Oracle 预定义异常,由 Oracle 自动抛出,让我们来看看 Oracle 都提供了哪些预定义异常,如下所示,我们可以根据名字很容易知道它们的意思。
Exception Name Error Code ACCESS_INTO_NULL -6530 CASE_NOT_FOUND -6592 COLLECTION_IS_NULL -6531 CURSOR_ALREADY_OPEN -6511 DUP_VAL_ON_INDEX -1 INVALID_CURSOR -1001 INVALID_NUMBER -1722 LOGIN_DENIED -1017 NO_DATA_FOUND +100 NO_DATA_NEEDED -6548 NOT_LOGGED_ON -1012 PROGRAM_ERROR -6501 ROWTYPE_MISMATCH -6504 SELF_IS_NULL -30625 STORAGE_ERROR -6500 SUBSCRIPT_BEYOND_COUNT -6533 SUBSCRIPT_OUTSIDE_LIMIT -6532 SYS_INVALID_ROWID -1410 TIMEOUT_ON_RESOURCE -51 TOO_MANY_ROWS -1422 VALUE_ERROR -6502 ZERO_DIVIDE -1476
Oracle 内部定义异常没有名字,只有错误代码(Error Code),如死锁(ORA-00060),它也是由 Oracle 自动抛出的,我们可以在 OTHERS 分支中捕获并处理它,通常我们不推荐这种做法。除此之外,我们还可以给内部定义异常起个名字,这样我们就可以单独处理它了,如下。
DECLARE NAME 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;
我们还可以自定义异常,自定义异常需要我们自己抛出,下面是一个简单的例子。
DECLARE NAME VARCHAR2(10); -- 自定义异常 NULL_POINT_EXCEPTION EXCEPTION; BEGIN IF NAME IS NULL THEN RAISE NULL_POINT_EXCEPTION; -- 抛出异常给调用者 END IF; END;
DECLARE NAME 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;
DECLARE NAME VARCHAR2(10); BEGIN IF NAME IS NULL THEN RAISE_APPLICATION_ERROR(-20000, 'name cannot null'); -- 抛出异常给调用者 END IF; END;
当 PL/SQL 抛出异常时,它并不会自动回滚事务,我们需要手动回滚,下面是一个简单的例子。
BEGIN UPDATE 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