數據庫程序設計4 Oracle異常處理

目錄

PL/SQL異常

異常類型

預定義異常

非預定義異常

捕獲異常的函數

用戶定義的異常

異常傳遞

Raise_Application_Error過程


PL/SQL異常

即運行時發生的錯誤。

異常的觸發:

  • 發生一個oracle錯誤時
  • 使用RAISE子句顯式觸發

處理異常:

  • 處理機截獲
  • 在調用環境中異常傳播

例子:

DECLARE
    v_ename    emp.ename%TYPE;
    v_empno    NUMBER(4) := 7369;
BEGIN
    select ename
    into v_ename
    from emp
    where empno=v_empno;
    dbms_output.put_line(v_ename);
EXCEPTION
    WHEN OTHERS THEN
    dbms_output.put_line('others');
END;

正常運行,輸出SMITH

當修改爲不存在的員工號時

DECLARE
    v_ename    emp.ename%TYPE;
    v_empno    NUMBER(4) := 736;
BEGIN
    select ename
    into v_ename
    from emp
    where empno=v_empno;
    dbms_output.put_line(v_ename);
EXCEPTION
    WHEN OTHERS THEN
    dbms_output.put_line('others');
END;

沒有這個數據,輸出others;如果沒有異常處理的話,程序則會終止掉。

異常類型

                       異常                         描述                                  處理
Oracle服務器預定義異常 Oracle中有名字的錯誤 不需聲明,可以由Oracle服務器隱式地觸發
Oracle 服務器非預定義的異常 其它所有非標準的Oracle服務器錯誤 在聲明部分聲明,可以由Oracle服務器隱式地觸發
用戶定義異常 由開發者決定的異常情形 在聲明部分聲明,由程序顯式地觸發

語法:

EXCEPTION
    WHEN exception1 [or exception2...] THEN
        statement;statement;...
    WHEN exception3 [or exception4...]THEN
        statement;statement;...
    [WHEN OTHERS THEN
        statement;statement;...]

注意:

  • 在異常部分WHEN子句沒有數量限制
  • WHEN OTHERS 是最後一 個子句
  • 異常處理部分從關鍵字EXCEPTION開始
  • 當異常拋出後,控制無條件轉到異常處理部分
  • 在離開塊之前只能執行一種異常處理

當程序出了異常的時候,程序正常的流程就不再走了。

預定義異常

異常情況名 錯誤代碼 描述
DUP_VAL_ON_INDEX 0RA-00001 試圖更新或插入重複記錄
INVALID_CURSOR 0RA-01001 非法遊標操作
INVALID_NUMBER 0RA-01722 字符串向數字轉換失敗
NO_DATA_FOUND ORA-01403 執行的SELECT沒有查到數據
TOO_MANY_ROWS ORA-01427 未使用遊標,SELECT語句返回了多行數據
VALUE_ERROR 0RA-06502 出現數字、數據轉換、字符串或限制型錯誤
ZERO_DIVIDE ORA-01476 被零除

非預定義異常

Oracle錯誤但是隻有代碼沒有名字。

DECLARE
    e_emp_cons    EXCPTION;    
    PRAGMA EXCEPTION_ INIT(e_emp_cons,-00001);

捕獲異常的函數

  • SQLCODE:返回錯誤代碼
  • SQLERRM:返回錯誤值相關聯的信息

例子

DECLARE
    v_ename    emp.ename%TYPE;
    v_empno    NUMBER(4) := 736;
BEGIN
    select ename
    into v_ename
    from emp
    where empno=v_empno;
    dbms_output.put_line(v_ename);
EXCEPTION
    WHEN OTHERS THEN
    dbms_output.put_line(SQLCODE);
    dbms_output.put_line(SQLERRM);
END;

但是在實際中,不會這樣輸出錯誤,而是會使用一個異常表來記錄

CREAT TABLE ERRORS(
objname VARCAHR2(100),
eDATE DATE,
SQLCODE NUMBER(6),
SQLERRM VARCHAR2(200)
)

那麼代碼可以改成

DECLARE
    v_ename    emp.ename%TYPE;
    v_empno    NUMBER(4) := 736;
    verrcode    NUMBER(6);
    v_errmsg    VARCHAR2(200);
BEGIN
    select ename
    into v_ename
    from emp
    where empno=v_empno;
    dbms_output.put_line(v_ename);
EXCEPTION
    WHEN OTHERS THEN
    verrcode := SQLCODE;
    v_errmsg := SQLERRM
    dbms_output.put_line(SQLCODE);
    dbms_output.put_line(SQLERRM);
    VALUES('',sysdate,verrcode,v_errmsg)
END;

這樣就可以把初始值放在一個表中。

用戶定義的異常

在oracle中不算錯誤但是我們覺得是錯誤。需要手動用RAISE子句觸發。

例子

DECLARE
    e_ too_ many    EXCEPTION;
BEGIN
    update emp
    set sal= 5000
    where deptno=&xp_ deptno;
    if SOL %ROWCOUNT >2 then
        RAISE e_ too_ many;
    end if;
EXCEPTION
    when e_ too_ many then
        dbms_ output.put_ line('漲工資人數'|| SQL%ROWCOUNT||'人,太多了);
        rollback;
End;

異常傳遞

異常如果沒有做處理,會向上一次傳。

Raise_Application_Error過程

模擬出現一個錯誤,產生一個類似於異常的對話框並終止程序,錯誤編號在-20000~-20999之間,錯誤消息長度最大爲2048字節

DECLARE
    e_ name    exception;
    pragma exception_ init(e_ name, 20202);
BEGIN
    delete from emp where deptno=90;
    if SQL%NOTFOUND then
        Raise_ Application_ Error(- 20202,’部門不存在);
    end if;
EXCEPTION
    when e_ name then
        dbms_ output. put line(sqlcode); 
        dbms_ output.put line(sqlerrm);
END;

這個代碼的作用是刪除人員時發現沒有這個部門,會彈出一個對話框並終止程序,提示部門不存在。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章