Oracle PL/SQL EXCEPTION處理

PL/SQL EXCEPTION的自訂與處理

前言

PL/SQL與一般其他程式一樣都提供了EXCEPTION處理,關於何謂EXCEPTION就不再此多加介紹了,相關的觀念與一般程式中的觀念是一樣的。

EXCEPTION處理

EXCEPTION區塊可宣告於函數或是程序中,基本使用語法如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[DECLARE]
    .....
BEGIN
   .....
EXCEPTION 
   WHEN 例外1 THEN 
      .....
   WHEN 例外2  THEN 
      .....
   WHEN 例外3 THEN 
      .....
   WHEN OTHERS THEN
      .....
END;

Oracle已內定了許多常見的EXCEPTION,可參考官方說明文件,以下進行相關的示範。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
SET FEEDBACK ON;
SET SERVEROUTPUT ON;
BEGIN
    INSERT INTO EXCEP_DEMO(TITLE) VALUES ('PHP 程式設計');
EXCEPTION
    -- 捕捉 DUP_VAL_ON_INDEX 例外
    WHEN DUP_VAL_ON_INDEX THEN
        DBMS_OUTPUT.PUT_LINE('PK 欄位值重複');
        -- SQLCODE 為錯誤碼
        DBMS_OUTPUT.PUT_LINE('SQL CODE: ' || SQLCODE);
        -- SQLERRM 為錯誤訊息
        DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
    -- 捕捉其他例外
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('資料庫操作發生錯誤');
END;

執行結果

1
2
3
PK 欄位值重複
SQL CODE: -1
SQLERRM: ORA-00001: unique constraint (OPEN楊藝Y.EXCEP_DEMO_PK) violated

使用者自訂EXCEPTION

使用者自訂例外可透過例外變數的宣告,再進行拋出。若不宣告例外變數,亦可透過RAISE_APPLICATION_ERROR(錯誤碼, 錯誤訊息)的方式拋出例外,不過此例外只可透過WHEN OTHERS THEN進行捕捉。

以下進行相關示範

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
DECLARE
    -- 宣告自訂的 EXCEPTION
    MY_EXCEPTION EXCEPTION;
BEGIN
    IF  1 > 0 THEN
        -- 拋出自訂的 EXCEPTION
        RAISE MY_EXCEPTION;
    END IF;
EXCEPTION
    -- 捕捉 MY_EXCEPTION 例外
    WHEN MY_EXCEPTION THEN
        DBMS_OUTPUT.PUT_LINE('我的 EXCEPTION 例外');
END;

執行結果

1
我的 EXCEPTION 例外

於自訂例外中依然可以自訂自己的錯誤編碼以及錯誤訊息,錯誤編碼範圍為-20000至-20999,使用方式直接透過範例進行說明。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
SET FEEDBACK OFF;
SET SERVEROUTPUT ON;
DECLARE
    -- 宣告自訂的 EXCEPTION
    MY_EXCEPTION EXCEPTION;
    -- 綁定錯誤名稱與錯誤碼
    PRAGMA EXCEPTION_INIT (MY_EXCEPTION, -20000);
BEGIN
    IF  1 > 0 THEN
        -- 拋出自訂的 EXCEPTION
        RAISE_APPLICATION_ERROR(-20000, '楊藝 自訂的例外');
    END IF;
EXCEPTION
    -- 捕捉 MY_EXCEPTION 例外
    WHEN MY_EXCEPTION THEN
        DBMS_OUTPUT.PUT_LINE('我的 EXCEPTION 例外');
        DBMS_OUTPUT.PUT_LINE('SQL CODE: ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
END;

執行結果

1
2
3
我的 EXCEPTION 例外
SQL CODE: -20000
SQLERRM: ORA-20000: 楊藝 自訂的例外