Oracle例外用法實(shí)例詳解
本文實(shí)例講述了Oracle例外用法。分享給大家供大家參考,具體如下:
一、例外分類
oracle將例外分為預(yù)定義例外、非預(yù)定義例外和自定義例外三種。
1)、預(yù)定義例外用于處理常見的oracle錯(cuò)誤。
2)、非預(yù)定義例外用于處理預(yù)定義例外不能處理的例外。
3)、自定義例外用于處理與oracle錯(cuò)誤無關(guān)的其它情況。
下面通過一個(gè)小案例演示如果不處理例外看會(huì)出現(xiàn)什么情況?
編寫一個(gè)存儲(chǔ)過程,可接收雇員的編號(hào),并顯示該雇員的姓名。
sql代碼如下:
SET SERVEROUTPUT ON; DECLARE V_ENAME EMP.ENAME%TYPE; BEGIN SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = &GNO; DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME); END; /
隨便輸入不存在的編號(hào),回車,會(huì)拋出如下異常:
ORA-01403: 未找到數(shù)據(jù)
ORA-06512: 在line 6
例外捕獲的sql代碼如下:
SET SERVEROUTPUT ON; DECLARE V_ENAME EMP.ENAME%TYPE; BEGIN SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = &GNO; DBMS_OUTPUT.PUT_LINE('名字:' || V_ENAME); EXCEPTION WHEN no_data_found THEN DBMS_OUTPUT.PUT_LINE('編號(hào)未找到!'); END; /
隨便輸入不存在的編號(hào),回車,會(huì)友情提示:編號(hào)未找到!
二、處理預(yù)定義例外
預(yù)定義例外是由pl/sql所提供的系統(tǒng)例外。當(dāng)pl/sql應(yīng)用程序違反了oracle規(guī)定的限制時(shí),則會(huì)隱含的觸發(fā)一個(gè)內(nèi)部例外。pl/sql為開發(fā)人員提供了二十多個(gè)預(yù)定義例外。我們給大家介紹常用的例外。
1)、case_not_found預(yù)定義例外
在開發(fā)pl/sql塊中編寫case語句時(shí),如果在when子句中沒有包含必須的條件分支,就會(huì)觸發(fā)case_not_found例外:
SET SERVEROUTPUT ON; CREATE OR REPLACE PROCEDURE SP_PRO6(SPNO NUMBER) IS V_SAL EMP.SAL%TYPE; BEGIN SELECT SAL INTO V_SAL FROM EMP WHERE EMPNO = SPNO; CASE WHEN V_SAL < 1000 THEN UPDATE EMP SET SAL = SAL + 100 WHERE EMPNO = SPNO; WHEN V_SAL < 2000 THEN UPDATE EMP SET SAL = SAL + 200 WHERE EMPNO = SPNO; END CASE; EXCEPTION WHEN CASE_NOT_FOUND THEN DBMS_OUTPUT.PUT_LINE('case語句沒有與' || V_SAL || '相匹配的條件'); END; / --調(diào)用存儲(chǔ)過程 SQL> EXEC SP_PRO6(7369);
case語句沒有與4444相匹配的條件
2)、cursor_already_open預(yù)定義例外
當(dāng)重新打開已經(jīng)打開的游標(biāo)時(shí),會(huì)隱含的觸發(fā)cursor_already_open例外
DECLARE CURSOR EMP_CURSOR IS SELECT ENAME, SAL FROM EMP; BEGIN OPEN EMP_CURSOR; --聲明時(shí)游標(biāo)已打開,所以沒必要再次打開 FOR EMP_RECORD1 IN EMP_CURSOR LOOP DBMS_OUTPUT.PUT_LINE(EMP_RECORD1.ENAME); END LOOP; EXCEPTION WHEN CURSOR_ALREADY_OPEN THEN DBMS_OUTPUT.PUT_LINE('游標(biāo)已經(jīng)打開'); END; /
3)、dup_val_on_index預(yù)定義例外
在唯一索引所對(duì)應(yīng)的列上插入重復(fù)的值時(shí),會(huì)隱含的觸發(fā)例外
BEGIN INSERT INTO DEPT VALUES (10, '公關(guān)部', '北京'); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN DBMS_OUTPUT.PUT_LINE('在deptno列上不能出現(xiàn)重復(fù)值'); END; /
4)、invalid_cursorn預(yù)定義例外
當(dāng)試圖在不合法的游標(biāo)上執(zhí)行操作時(shí),會(huì)觸發(fā)該例外
例如:試圖從沒有打開的游標(biāo)提取數(shù)據(jù),或是關(guān)閉沒有打開的游標(biāo)。則會(huì)觸發(fā)該例外
DECLARE CURSOR EMP_CURSOR IS SELECT ENAME, SAL FROM EMP; EMP_RECORD EMP_CURSOR%ROWTYPE; BEGIN --open emp_cursor; --打開游標(biāo) FETCH EMP_CURSOR INTO EMP_RECORD; DBMS_OUTPUT.PUT_LINE(EMP_RECORD.ENAME); CLOSE EMP_CURSOR; EXCEPTION WHEN INVALID_CURSOR THEN DBMS_OUTPUT.PUT_LINE('請(qǐng)檢測(cè)游標(biāo)是否打開'); END; /
5)、invalid_number預(yù)定義例外
當(dāng)輸入的數(shù)據(jù)有誤時(shí),會(huì)觸發(fā)該例外
比如:數(shù)字100寫成了loo就會(huì)觸發(fā)該例外
SET SERVEROUTPUT ON; BEGIN UPDATE EMP SET SAL = SAL + 'AAA'; EXCEPTION WHEN INVALID_NUMBER THEN DBMS_OUTPUT.PUT_LINE('輸入的數(shù)字不正確'); END; /
6)、no_data_found預(yù)定義例外
下面是一個(gè)pl/sql 塊,當(dāng)執(zhí)行select into沒有返回行,就會(huì)觸發(fā)該例外
SET serveroutput ON; DECLARE V_SAL EMP.SAL%TYPE; BEGIN SELECT SAL INTO V_SAL FROM EMP WHERE ENAME = 'ljq'; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('不存在該員工'); END; /
7)、too_many_rows預(yù)定義例外
當(dāng)執(zhí)行select into語句時(shí),如果返回超過了一行,則會(huì)觸發(fā)該例外。
DECLARE V_ENAME EMP.ENAME%TYPE; BEGIN SELECT ENAME INTO V_ENAME FROM EMP; EXCEPTION WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('返回了多行'); END; /
8)、zero_divide預(yù)定義例外
當(dāng)執(zhí)行2/0語句時(shí),則會(huì)觸發(fā)該例外
9)、value_error預(yù)定義例外
當(dāng)在執(zhí)行賦值操作時(shí),如果變量的長(zhǎng)度不足以容納實(shí)際數(shù)據(jù),則會(huì)觸發(fā)該例外value_error
其它預(yù)定義例外(這些例外不是在pl/sql里觸發(fā)的,而是在用oracle時(shí)觸發(fā)的,所以取名叫其它預(yù)定義例外)
1、login_denied
當(dāng)用戶非法登錄時(shí),會(huì)觸發(fā)該例外
2、not_logged_on
如果用戶沒有登錄就執(zhí)行dml操作,就會(huì)觸發(fā)該例外
3、storage_error
如果超過了內(nèi)存空間或是內(nèi)存被損壞,就觸發(fā)該例外
4、timeout_on_resource
如果oracle在等待資源時(shí),出現(xiàn)了超時(shí)就觸發(fā)該例外
三、非預(yù)定義例外
非預(yù)定義例外用于處理與預(yù)定義例外無關(guān)的oracle錯(cuò)誤。使用預(yù)定義例外只能處理21個(gè)oracle 錯(cuò)誤,而當(dāng)使用pl/sql開發(fā)應(yīng)用程序時(shí),可能會(huì)遇到其它的一些oracle錯(cuò)誤。比如在pl/sql塊中執(zhí)行dml語句時(shí),違反了約束規(guī)定等等。在這樣的情況下,也可以處理oracle的各種例外,因?yàn)榉穷A(yù)定義例外用的不多,這里我就不舉例了。
四、處理自定義例外
預(yù)定義例外和自定義例外都是與oracle錯(cuò)誤相關(guān)的,并且出現(xiàn)的oracle 錯(cuò)誤會(huì)隱含的觸發(fā)相應(yīng)的例外;而自定義例外與oracle 錯(cuò)誤沒有任何關(guān)聯(lián),它是由開發(fā)人員為特定情況所定義的例外.
問題:請(qǐng)編寫一個(gè)pl/sql 塊,接收一個(gè)雇員的編號(hào),并給該雇員工資增加1000元,如果該雇員不存在,請(qǐng)?zhí)崾尽?/p>
CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS BEGIN UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO; END; / --調(diào)用存儲(chǔ)過程, EXEC EX_TEST(56);
這里,編號(hào)為56 是不存在的,剛才的報(bào)異常了,為什么現(xiàn)在不報(bào)異常呢?
因?yàn)閯偛诺氖莝elect語句
怎么解決這個(gè)問題呢? 修改代碼,如下:
--自定義例外 CREATE OR REPLACE PROCEDURE EX_TEST(SPNO NUMBER) IS --定義一個(gè)例外 MYEX EXCEPTION; BEGIN --更新用戶sal UPDATE EMP SET SAL = SAL + 1000 WHERE EMPNO = SPNO; --sql%notfound 這是表示沒有update --raise myex;觸發(fā)myex IF SQL%NOTFOUND THEN RAISE MYEX; END IF; EXCEPTION WHEN MYEX THEN DBMS_OUTPUT.PUT_LINE('沒有更新任何用戶'); END; /
現(xiàn)在再測(cè)試一次:
SQL> exec ex_test(56);
沒有更新任何用戶
希望本文所述對(duì)大家Oracle數(shù)據(jù)庫(kù)程序設(shè)計(jì)有所幫助。
相關(guān)文章
Oracle實(shí)現(xiàn)行轉(zhuǎn)換成列的方法
這篇文章主要介紹了Oracle實(shí)現(xiàn)行轉(zhuǎn)換成列的方法,實(shí)例分析了Oracle創(chuàng)建及查詢表的相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12Oracle SQL Developer連接報(bào)錯(cuò)(ORA-12505)的解決方案(兩種)
本篇文章通過兩種方案幫大家解決Oracle SQL Developer連接報(bào)錯(cuò)(ORA-12505),需要的朋友可以參考下2015-10-10oracle11g密碼復(fù)雜性校驗(yàn)開啟關(guān)閉方式
這篇文章主要介紹了oracle11g密碼復(fù)雜性校驗(yàn)開啟關(guān)閉方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12oracle數(shù)據(jù)庫(kù)查看鎖表的sql語句整理
Oracle數(shù)據(jù)庫(kù)操作中,我們有時(shí)會(huì)用到鎖表查詢以及解鎖和kill進(jìn)程等操作,這篇文章主要給大家介紹了關(guān)于oracle數(shù)據(jù)庫(kù)查看鎖表的sql語句的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10Oracle聯(lián)機(jī)日志文件與歸檔文件詳細(xì)介紹
這篇文章主要介紹了Oracle聯(lián)機(jī)日志文件與歸檔文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-11-11oracle ORA-01114、ORA-27067錯(cuò)誤解決方法
本文章總結(jié)了關(guān)于ORA-01114、ORA-27067錯(cuò)誤解決方法,有需要學(xué)習(xí)的朋友可參考一下下哦2012-10-10安裝oracle11g INS-30131執(zhí)行安裝程序驗(yàn)證所需的初始設(shè)置失敗的解決方法
這篇文章主要為大家詳細(xì)介紹了安裝oracle11g INS-30131執(zhí)行安裝程序驗(yàn)證所需的初始設(shè)置失敗的解決方法,感興趣的小伙伴們可以參考一下2016-07-07