国产成人精品亚洲777人妖,欧美日韩精品一区视频,最新亚洲国产,国产乱码精品一区二区亚洲

您的位置:首頁技術(shù)文章
文章詳情頁

Oracle對(duì)PL/SQL中的異常處理

瀏覽:212日期:2023-03-12 15:25:10
目錄
  • 一、異常處理
    • 1、三種的異常類型:
    • 2、異常的SQLCode 和 SQLERRM
  • 二、處理預(yù)定義例外
    • 常見錯(cuò)誤預(yù)定義的名稱
  • 三、處理非預(yù)定義例外(exception_init)
    • 四、處理自定義例外(通過Raise )
      • 五、應(yīng)用程序的異常處理。(通過Raise_Application_Error )

        一、異常處理

        PL/SQL提供了良好的異常處理機(jī)制,當(dāng)程序運(yùn)行出現(xiàn)錯(cuò)誤時(shí)就會(huì)觸發(fā)異常。異常被觸發(fā)時(shí),程序執(zhí)行即終止,在PL/SQL塊中提供了異常處理的部分,從而可以捕獲一個(gè)異常進(jìn)行特殊處理。

        1、三種的異常類型:

        • 預(yù)定義 ( Predefined )錯(cuò)誤:
          --ORACLE預(yù)定義的異常情況大約有24個(gè)。對(duì)這種異常情況的處理,無需在程序中定義,由ORACLE自動(dòng)將其引發(fā)。
        • 非預(yù)定義 ( Predefined )錯(cuò)誤:
          --即其他標(biāo)準(zhǔn)的ORACLE錯(cuò)誤。對(duì)這種異常情況的處理,需要用戶在程序中定義,然后由ORACLE自動(dòng)將其引發(fā)。
        • 用戶定義(User_define) 錯(cuò)誤:
          --程序執(zhí)行過程中,出現(xiàn)編程人員認(rèn)為的非正常情況。對(duì)這種異常情況的處理,需要用戶在程序中定義,然后顯式地在程序中將其引發(fā)。

        2、異常的SQLCode 和 SQLERRM

        EXCEPTIONWHEN first_exception THEN <code to handle first exception >WHEN second_exception THEN <code to handle second exception >WHEN OTHERS THEN <code to handle others exception >END;

        由于ORACLE 的錯(cuò)信息最大長度是512字節(jié),為了得到完整的錯(cuò)誤提示信息,我們可用 SQLERRM和 SUBSTR 函數(shù)一起得到錯(cuò)誤提示信息,方便進(jìn)行錯(cuò)誤,特別是如果WHEN OTHERS異常處理器時(shí)更為方便。

        • SQLCODE 返回遇到的Oracle 錯(cuò)誤號(hào)
        • SQLERRM 返回遇到的Oracle錯(cuò)誤信息

        二、處理預(yù)定義例外

        對(duì)這種異常情況的處理,只需在PL/SQL塊的異常處理部分,直接引用相應(yīng)的異常情況名,并對(duì)其完成相應(yīng)的異常錯(cuò)誤處理即可。

        常見錯(cuò)誤預(yù)定義的名稱

        • ACCESS_INTO_NULL(ORA-06530):引用對(duì)象類型變量的屬性時(shí),未對(duì)變量進(jìn)行初始化;
        • CASE_NOT_FOUND(ORA-06592):使用case-when結(jié)構(gòu)時(shí),未使用else子句,并且處理了不包含的case條件;
        • COLLECTION_IS_NULL(ORA-06531):引用集合類型元素時(shí),未對(duì)集合類型變量初始化;
        • CURSOR_ALREADY_OPEN(ORA-06511):使用open命令打開已經(jīng)處于打開狀態(tài)的顯式游標(biāo);
        • DUL_VAL_ON_INDEX(ORA-00001):在唯一約束的列上插入重復(fù)的值時(shí)會(huì)觸發(fā);
        • INVALID_NUMBER(ORA-01722):不能將字符轉(zhuǎn)換為合理的數(shù)字時(shí)會(huì)觸發(fā);
        • NO_DATA_FOUND(ORA-01403):select語句未返回行或引用未初始化的索引表元素;
        • TOO_MANY_ROWS(ORA-01422):select into時(shí),返回?cái)?shù)據(jù)超過一行時(shí)即被觸發(fā);
        • ZERO_DEVIDE(ORA-01476):除0異常;
        • SUBSCRIPT_BEYOUND_COUNT(ORA-06533):使用數(shù)組類型是,下標(biāo)超出元素范圍;
        • SUBSCRIPT_OUTSIDE_LIMIT(ORA-06532):使用嵌套表或Varry元素時(shí),使用了負(fù)數(shù)作為下標(biāo);
        • VALUE_ERROR(ORA-06502):賦值操作時(shí),變量長度不足以容納實(shí)際數(shù)據(jù)長度
        • ROWTYPE_MISMATCH(ORA-06504):位游標(biāo)變量賦值時(shí),返回類型與游標(biāo)定義類型不一致
        --例1:更新指定員工工資,如工資小于1500,則加100;DECLARE   v_empno employees.employee_id%TYPE := &empno;   v_sal   employees.salary%TYPE;BEGIN   SELECT salary INTO v_sal FROM employees WHERE employee_id = v_empno;   IF v_sal<=1500 THEN UPDATE employees SET salary = salary + 100 WHERE employee_id=v_empno; DBMS_OUTPUT.PUT_LINE(‘編碼為‘||v_empno||‘員工工資已更新!‘);        ELSEDBMS_OUTPUT.PUT_LINE(‘編碼為‘||v_empno||‘員工工資已經(jīng)超過規(guī)定值!‘);   END IF;EXCEPTION   WHEN NO_DATA_FOUND THEN        DBMS_OUTPUT.PUT_LINE(‘?dāng)?shù)據(jù)庫中沒有編碼為‘||v_empno||‘的員工‘);   WHEN TOO_MANY_ROWS THEN      DBMS_OUTPUT.PUT_LINE(‘程序運(yùn)行錯(cuò)誤!請(qǐng)使用游標(biāo)‘);   WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);END;

        三、處理非預(yù)定義例外(exception_init)

        對(duì)于這類異常情況的處理,首先必須對(duì)非定義的ORACLE錯(cuò)誤進(jìn)行定義。步驟如下:

        • 在PL/SQL 塊的定義部分定義異常情況:
        <異常情況> EXCEPTION;
        • 將系統(tǒng)異常轉(zhuǎn)為用戶定義異常:將其定義好的異常情況,與標(biāo)準(zhǔn)的ORACLE錯(cuò)誤聯(lián)系起來,使用EXCEPTION_INIT語句:
        PRAGMA EXCEPTION_INIT(<異常情況>, <錯(cuò)誤代碼>);

        舉例:

        --例2:刪除指定部門的記錄信息,以確保該部門沒有員工。 INSERT INTO departments VALUES(50, ‘FINANCE‘, ‘CHICAGO‘);DECLARE   v_deptno departments.department_id%TYPE := &deptno;   deptno_remaining EXCEPTION;--定義一個(gè)異常變量   PRAGMA EXCEPTION_INIT(deptno_remaining, –2292); /* -2292 是違反一致性約束的錯(cuò)誤代碼 */BEGIN   DELETE FROM departments WHERE department_id = v_deptno;EXCEPTION   WHEN deptno_remaining THEN       DBMS_OUTPUT.PUT_LINE(‘違反數(shù)據(jù)完整性約束!‘);   WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);END;

        四、處理自定義例外(通過Raise )

        當(dāng)與一個(gè)異常錯(cuò)誤相關(guān)的錯(cuò)誤出現(xiàn)時(shí),就會(huì)隱含觸發(fā)該異常錯(cuò)誤。用戶定義的異常錯(cuò)誤是通過顯式使用 RAISE 語句來觸發(fā)。當(dāng)引發(fā)一個(gè)異常錯(cuò)誤時(shí),控制就轉(zhuǎn)向到 EXCEPTION塊異常錯(cuò)誤部分,執(zhí)行錯(cuò)誤處理代碼。對(duì)于這類異常情況的處理,步驟如下:

        • 在PL/SQL 塊的定義部分定義異常情況:
        <異常情況> EXCEPTION;RAISE <異常情況>;
        • 在PL/SQL 塊的異常情況處理部分對(duì)異常情況做出相應(yīng)的處理。
        --例3:更新指定員工工資,增加100; DECLARE   v_empno employees.employee_id%TYPE :=&empno;   no_result  EXCEPTION;-定義異常BEGIN   UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;   IF SQL%NOTFOUND THEN      RAISE no_result;//觸發(fā)異常   END IF;EXCEPTION   WHEN no_result THEN //捕捉異常      DBMS_OUTPUT.PUT_LINE(‘你的數(shù)據(jù)更新語句失敗了!‘);   WHEN OTHERS THEN      DBMS_OUTPUT.PUT_LINE(SQLCODE||‘—‘||SQLERRM);

        五、應(yīng)用程序的異常處理。(通過Raise_Application_Error )

        調(diào)用DBMS_STANDARD(ORACLE提供的包)包所定義的RAISE_APPLICATION_ERROR過程,可以重新定義異常錯(cuò)誤消息,它為應(yīng)用程序提供了一種與ORACLE交互的方法。

        RAISE_APPLICATION_ERROR 的語法如下:

        RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] );
        • error_number:從 –20,000 到 –20,999 之間的參數(shù),
        • error_message:是相應(yīng)的提示信息(< 2048 字節(jié)),
        • keep_errors:可選,如果keep_errors =TRUE ,則新錯(cuò)誤將被添加到已經(jīng)引發(fā)的錯(cuò)誤列表中。如果keep_errors=FALSE(缺省),則新錯(cuò)誤將替換當(dāng)前的錯(cuò)誤列表。

        例:創(chuàng)建一個(gè)函數(shù)get_salary, 該函數(shù)檢索指定部門的工資總和,其中定義了-20991和-20992號(hào)錯(cuò)誤,分別處理參數(shù)為空和非法部門代碼兩種錯(cuò)誤:

        CREATE OR REPLACE FUNCTION get_salary(p_deptno NUMBER) #函數(shù)檢索指定部門的工資總和RETURN NUMBER AS  v_sal NUMBER; #函數(shù)get_salary返回v_sal值BEGIN  IF p_deptno IS NULL THEN    RAISE_APPLICATION_ERROR(–20991, "部門代碼為空"); #用戶定義的異常處理  ELSIF p_deptno<0 THEN    RAISE_APPLICATION_ERROR(–20992, "無效的部門代碼");  ELSE    SELECT SUM(employees.salary) INTO v_sal FROM employees     WHERE employees.department_id=p_deptno;    RETURN v_sal;  END IF;

        調(diào)用函數(shù)

        DECLARE   V_salary NUMBER(7,2);  V_sqlcode NUMBER;  V_sqlerr VARCHAR2(512);  Null_deptno EXCEPTION;  #定義異常情況  Invalid_deptno EXCEPTION; #定義異常情況  PRAGMA EXCEPTION_INIT(null_deptno,–20991);  #非預(yù)定義的異常,將它與oracle錯(cuò)誤聯(lián)系起來  PRAGMA EXCEPTION_INIT(invalid_deptno, –20992); #非預(yù)定義的異常,將它與oracle錯(cuò)誤聯(lián)系起來BEGIN  BEGIN    V_salary :=get_salary(–10);  EXCEPTION    WHEN invalid_deptno THEN      V_sqlcode :=SQLCODE;      V_sqlerr  :=SQLERRM;      INSERT INTO errlog(errcode, errtext) VALUES(v_sqlcode, v_sqlerr); #將錯(cuò)誤SQLCODE及SQLERRM存入到表errlog中        COMMIT;  END ;

        例:定義觸發(fā)器,使用RAISE_APPLICATION_ERROR阻止沒有員工姓名的新員式記錄插入:

        CREATE OR REPLACE TRIGGER tr_insert_empBEFORE INSERT ON employeesFOR EACH ROWBEGIN  IF :new.first_name IS NULL OR :new.last_name is null THEN    RAISE_APPLICATION_ERROR(–20000,‘Employee must have a name.‘);  END IF;

        到此這篇關(guān)于Oracle對(duì)PL/SQL異常處理的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持。

        標(biāo)簽: Oracle
        相關(guān)文章:
        主站蜘蛛池模板: 高阳县| 板桥市| 上饶市| 上虞市| 乐亭县| 关岭| 奉节县| 武平县| 依兰县| 阳西县| 芦山县| 锦屏县| 靖江市| 龙江县| 宁明县| 保亭| 东港市| 无极县| 黔西县| 甘肃省| 东兰县| 包头市| 黄龙县| 合山市| 从江县| 香港| 准格尔旗| 潼关县| 雷波县| 遵化市| 吴忠市| 酒泉市| 内江市| 淳安县| 贵港市| 台北市| 利津县| 石阡县| 都匀市| 探索| 松原市|