畢 桂 徐 霖
無錫工藝職業(yè)技術(shù)學(xué)院,江蘇 宜興 214206
談?wù)凮racle數(shù)據(jù)庫異常處理
畢 桂 徐 霖
無錫工藝職業(yè)技術(shù)學(xué)院,江蘇 宜興 214206
進(jìn)行Oracle數(shù)據(jù)庫開發(fā)中,在程序的運(yùn)行過程中,可能會(huì)因?yàn)楦鞣N原因發(fā)生這樣或那樣的錯(cuò)誤,就需要針對(duì)錯(cuò)誤進(jìn)行處理,異常處理就是這樣的一段程序。有了異常處理就可以提高我們的程序代碼質(zhì)量,一個(gè)好的程序都必含有能夠處理發(fā)生的任何錯(cuò)誤。PL/SQL用異常和異常處理器來實(shí)現(xiàn)錯(cuò)誤處理,它的異常處理機(jī)制提供了能夠處理前面未處理異常的功能。
Oracle數(shù)據(jù)庫;程序代碼;異常處理;PL/SQL
Oracle中出現(xiàn)錯(cuò)誤的情形通常分為程序在編譯時(shí)錯(cuò)誤(compile-time error)和程序在運(yùn)行時(shí)錯(cuò)誤(run-timeerror)。一個(gè)程序在處理運(yùn)行時(shí)出現(xiàn)錯(cuò)誤,這是異常處理,一個(gè)程序在編譯時(shí)的錯(cuò)誤,并不是異常處理,我們這里所說的異常處理是指程序通過編譯沒有錯(cuò)誤,而是在程序運(yùn)行中出現(xiàn)的錯(cuò)誤。當(dāng)程序在運(yùn)行時(shí)發(fā)生錯(cuò)誤,異常被觸發(fā),程序的正常執(zhí)行過程被終止,程序無條件轉(zhuǎn)到異常處理部分,在Oracle數(shù)據(jù)庫允許聲明其他異常條件類型以擴(kuò)展錯(cuò)誤/異常處理,有了這樣的擴(kuò)展使PL/SQL的異常處理非常靈活。在Oracle數(shù)據(jù)庫中,PL/SQL將異常分為預(yù)定義異常和用戶定義異常。
(一)預(yù)定義異常
Oracle數(shù)據(jù)庫自身為用戶提供了大量的、可以在PL/SQL中使用的預(yù)定以異常,方便用戶檢查代碼失敗的一般原因,它們都定義在Oracle的核心PL/SQL中。每當(dāng)PL/SQL違背了Oracle原則或超越了系統(tǒng)依賴的原則時(shí)就會(huì)隱式的產(chǎn)生內(nèi)部異常。每個(gè)Oracle錯(cuò)誤都有一個(gè)號(hào)碼,在PL/SQL中通過名字處理預(yù)定義異常,PL/SQL為一些Oracle公共錯(cuò)誤進(jìn)行了預(yù)定義。如SELECT INTO語句返回多行數(shù)據(jù)時(shí),PL/SQL就會(huì)觸發(fā)預(yù)定義異常TOO_MANY_ROWS。
(二)自定義異常
用戶自定義異常不一定必須是Oracle返回的系統(tǒng)錯(cuò)誤,這些錯(cuò)誤Oracle數(shù)據(jù)庫本身無法知曉,也不能控制。用戶可以在自己的應(yīng)用程序中創(chuàng)建可觸發(fā)及可處理的自定義異常,和預(yù)定義異常不同的是,用戶定義的異常,系統(tǒng)不會(huì)自動(dòng)觸發(fā)(這種異常對(duì)系統(tǒng)來說不一定是錯(cuò)誤),需要用戶來觸發(fā)異常,另外用戶定義的異常,需要在聲明部分定義。用戶定義的異常處理部分基本上和預(yù)定義異常相同。
Oracle數(shù)據(jù)庫內(nèi)部預(yù)定義異常僅僅20個(gè)左右,而在實(shí)際程序運(yùn)行過程中產(chǎn)生的異常情況就會(huì)很多,為此Oracle數(shù)據(jù)庫經(jīng)常使用錯(cuò)誤編號(hào)和相關(guān)描述給出異常信息。數(shù)據(jù)庫設(shè)計(jì)人員常常會(huì)根據(jù)實(shí)際的業(yè)務(wù)邏輯情況定義一些特殊異常。Oracle數(shù)據(jù)庫的自定義異常可以分為錯(cuò)誤編號(hào)異常和業(yè)務(wù)邏輯異常。
(一)錯(cuò)誤編號(hào)異常
錯(cuò)誤編號(hào)異常是指Oracle數(shù)據(jù)庫系統(tǒng)發(fā)生錯(cuò)誤時(shí),系統(tǒng)就會(huì)顯示出錯(cuò)誤編號(hào)和相關(guān)信息的異常。用戶可以根據(jù)錯(cuò)誤編號(hào)來完成異常處理,由于錯(cuò)誤編號(hào)比較抽象,不便于用戶理解和記憶。對(duì)于這種類型的異常,首先在Oracle數(shù)據(jù)中PL/SQL塊的聲明部分使用EXCEPTION類型定義一個(gè)異常變量名,然后使用語句PRAGMA EXCEPTION _INIT為“錯(cuò)誤編號(hào)”關(guān)聯(lián)這個(gè)異常變量名,最后可以像對(duì)待Oracle數(shù)據(jù)庫系統(tǒng)預(yù)定義異常一樣處理了。我們通過一個(gè)實(shí)例,來說明一下,我們錯(cuò)誤編號(hào)異常的使用。假設(shè)我們?cè)贠racle數(shù)據(jù)庫中已經(jīng)創(chuàng)建了一個(gè)表單,名為student(編號(hào)(id),姓名(name),性別(sex))
declare
primary_id exception;——定義一個(gè)異常變量
pragma exception_init(primary_id,-00001);——關(guān)聯(lián)錯(cuò)誤號(hào)和異常變量名
begin
insert into student values(2,'張三','男');——向student表中插入一條與已有主鍵值重復(fù)的記錄,以便引發(fā)異常
exception
when primary_id then ——若oracle捕獲到的異常為-00001異常
dbms_output.put_line('主鍵已存在,不允許重復(fù)!');——輸出異常描述信息
end;
通過運(yùn)行結(jié)果可以看到,使用異常處理機(jī)制可以預(yù)防Oracle數(shù)據(jù)庫系統(tǒng)因?yàn)橐l(fā)異常而導(dǎo)致程序崩潰的作用,它可以讓我們書寫的程序有機(jī)會(huì)進(jìn)行自動(dòng)檢測(cè)和修改錯(cuò)誤。從上面的例子可以看出自定義異常比較容易理解和記憶,也方便數(shù)據(jù)庫人員使用。
(二)業(yè)務(wù)邏輯異常
在數(shù)據(jù)庫的實(shí)際開發(fā)過程中,數(shù)據(jù)庫開發(fā)人員有時(shí)會(huì)根據(jù)開發(fā)對(duì)象的業(yè)務(wù)邏輯情況自己定義一個(gè)異常,通過這種方法來提醒數(shù)據(jù)庫開發(fā)人員操作違反業(yè)務(wù)邏輯規(guī)則,從而引發(fā)自己定義的異常,中斷程序的運(yùn)行來進(jìn)行自定義異常的處理。業(yè)務(wù)邏輯異常首先是需要在DECLARE進(jìn)行聲明一個(gè)異常變量;然后在BEGIN過程中先給出需要的業(yè)務(wù)邏輯規(guī)則再執(zhí)行RAISE語句;最后在EXCEPTION中進(jìn)行編寫對(duì)異常進(jìn)行處理的程序語句。下面我們通過一個(gè)實(shí)例來看看如何定義和引發(fā)業(yè)務(wù)邏輯異常:
declare
null_exception exception;——聲明一個(gè)異常變量
S student %rowtype;
begin
S.id:=3;——ID是主鍵進(jìn)行賦值,
insert into student values(S.id,S.name,S.sex);——向student表中插入一條記錄
if S.name is null then ——判斷表的name的值是否為空
raise null_exception;——引發(fā)異常,進(jìn)行異常處理
end if;
exception
when null_exception then
dbms_output.put_line('name不可以為空');——當(dāng)引發(fā)異常時(shí),輸出異常信息
rollback;
end;
通過運(yùn)行結(jié)果可以看到,業(yè)務(wù)邏輯異常定義成功。程序就可以進(jìn)行檢測(cè)我們向數(shù)據(jù)庫表單STUDENT中插入數(shù)據(jù)時(shí)是否存在學(xué)生NAME為空的情況了。
總的來看,在一段沒有語法錯(cuò)誤的程序代碼中,因?yàn)槌霈F(xiàn)了不太“合格”數(shù)據(jù)而導(dǎo)致程序無法運(yùn)行。我們希望提高自己的代碼質(zhì)量,使得我們的程序更加健壯,我們對(duì)程序做了異常處理。從上面的異常處理過程中,我們可以看出:對(duì)于預(yù)定義異常和錯(cuò)誤編號(hào)異常是由我們Oracle數(shù)據(jù)庫系統(tǒng)判斷的,但是對(duì)于業(yè)務(wù)邏輯異常,我們Oracle數(shù)據(jù)庫系統(tǒng)本身就無法知道了,通常我們是通過一個(gè)引發(fā)異常的機(jī)制(RAISE語句)來完成,從而可以實(shí)現(xiàn)對(duì)業(yè)務(wù)邏輯規(guī)則的判斷。
[1]劉竹林.數(shù)據(jù)庫設(shè)計(jì)與Oracle數(shù)據(jù)庫應(yīng)用教程.清華大學(xué)出版社,北京大學(xué)出版,2009.
[2]張曉林,吳斌,晁陽.Oracle數(shù)據(jù)庫開發(fā)基礎(chǔ)教程.清華大學(xué)出版社,2009.
[3]趙宇蘭.Oracle數(shù)據(jù)庫應(yīng)用技術(shù).合肥工業(yè)大學(xué)出版社,2014.
TP
A
1006-0049-(2017)17-0187-01