PL/SQL(Procedural Language/SQL,過(guò)程語(yǔ)言/SQL)是結(jié)合了Oracel過(guò)程語(yǔ)言和結(jié)構(gòu)化查詢語(yǔ)言(SQL)的一種擴(kuò)展語(yǔ)言。
優(yōu)點(diǎn):
(1)PL/SQL具有編程語(yǔ)言的特點(diǎn),它能把一組SQL語(yǔ)句放到一個(gè)模塊中,使其更具模塊化種序的特點(diǎn)。
(2)PL/SQL可以采用過(guò)程性語(yǔ)言控制程序的結(jié)構(gòu)。
(3)PL/SQL有自動(dòng)處理的異常處理機(jī)制。
(4)PL/SQL程序塊具有更好的可移植性,可移植到另一個(gè)Oracle數(shù)據(jù)庫(kù)中。
(5)PL/SQL程序減少了網(wǎng)絡(luò)的交互,有助于提高程序性能。
在OraclePL/SQL語(yǔ)句塊中exception的異常處理部分是非常重要的組成部分,它決定了在PL/SQL語(yǔ)句塊內(nèi)部可執(zhí)行部分在發(fā)生異常錯(cuò)誤時(shí),程序是友好地提示:程序遇到某些錯(cuò)誤而無(wú)法執(zhí)行,還是拋出一堆難以理解的Oracle內(nèi)部錯(cuò)誤碼。
本文只介紹3種PL/SQL異常的三種高級(jí)形態(tài),用于解決Oracle內(nèi)置異常過(guò)少,很多時(shí)候不能夠滿足實(shí)際的使用需求。
1,RAISE_APPLICATION_ERROR
- 是Oracle提供的一種特殊的內(nèi)置過(guò)程,允許程序員為特定的程序創(chuàng)建有意義的錯(cuò)誤消息,適用于用戶自定義定義異常。
- 語(yǔ)法結(jié)構(gòu)
RAISE_APPLICATION_ERROR (error_number,error_message);或者
RAISE_APPLICATION_ERROR (error_number,error_message,keep_errors)
- error_number 是與特定錯(cuò)誤消息關(guān)聯(lián)的錯(cuò)誤編號(hào),Oracle預(yù)留了-20999 -- -20000專門提供給程序員自定義錯(cuò)誤代碼。
- error_message 是錯(cuò)誤消息文本,最多包含2048個(gè)字符。
- keep_errors 是可選的Boolean參數(shù),默認(rèn)為FALSE,如果為TRUE,新拋出的錯(cuò)誤會(huì)被添加到已拋出的錯(cuò)誤列表中,這個(gè)錯(cuò)誤列表稱為錯(cuò)誤棧,如果為FALSE,新錯(cuò)誤會(huì)替換已拋出的錯(cuò)誤棧。
- 適用于未命名的用戶定義異常,負(fù)責(zé)把錯(cuò)誤編號(hào)和錯(cuò)誤消息關(guān)聯(lián),用戶定義了異常,卻沒有定義該錯(cuò)誤的名稱
- 使用RAISE_APPLICATION_ERROR過(guò)程,程序員能夠遵循與Oracle一致的方式返回錯(cuò)誤消息。
- 示例代碼
declare
v_id number := p_id;
v_name varchar2(20);
v_sal number;
begin
if v_id > 0 then
select ename,sal into v_name,v_sal from emp where empno = v_id;
dbms_output.put_line(chr(10)||v_name||' '||v_sal);
else
raise_application_error (-20001,'Employee id can not be negative.');
end if;
exception
when NO_DATA_FOUND then
dbms_output.put_line(chr(10)||'There is no such employee id is '||v_id);
end;
/
Enter value for p_id: 40
old 2: v_id number := p_id;
new 2: v_id number := 40;
There is no such employee id is 40
PL/SQL procedure successfully completed.
/
Enter value for p_id: -90
old 2: v_id number := p_id;
new 2: v_id number := -90;
declare
*
ERROR at line 1:
ORA-20001: Employee id can not be negative.
ORA-06512: at line 11
- 示例解析:該P(yáng)L/SQL代碼會(huì)根據(jù)用戶輸入的員工Id,查詢員工的姓名和工資。當(dāng)我們輸入存在的員工編號(hào)時(shí),程序能夠正常返回結(jié)果;如果輸入不存在ID,則select into語(yǔ)句會(huì)拋出沒有返回行,進(jìn)而使程序進(jìn)入異常處理部分(本部分為舉例),程序同樣執(zhí)行成功;當(dāng)輸入一個(gè)負(fù)數(shù)時(shí),if條件語(yǔ)句就會(huì)進(jìn)入到raise_application_error部分,由于可執(zhí)行部分運(yùn)行發(fā)生錯(cuò)誤,執(zhí)行焦點(diǎn)會(huì)立即轉(zhuǎn)移到異常處理部分,而異常處理部分沒有關(guān)于該異常的處理,所以程序報(bào)錯(cuò),并返回到用戶界面。
- 是喲個(gè)raise_application_error,程序員可以使程序?qū)崿F(xiàn)像Oracle系統(tǒng)產(chǎn)生的錯(cuò)誤消息。
- 事實(shí)上,單純使用raise_application_error,因?yàn)闆]有異常的名稱,如果要對(duì)其進(jìn)行異常處理,只能夠使用others(下文有專門的介紹)。
2,EXCEPTION_INIT
- 使用EXCEPTION_INIT編譯指令,可以將用戶自定義的Oracle錯(cuò)誤編號(hào)和用戶自定義的錯(cuò)誤名稱關(guān)聯(lián)起來(lái),相當(dāng)于用戶自定義錯(cuò)誤和RAISE_APPLICATION_ERROR的結(jié)合體。
- EXCEPTION_INIT 出現(xiàn)在語(yǔ)句塊的聲明部分:
exception_name exception;
pragma exception_init(exception_name,error_code)
- 考慮如下代碼:
declare
v_no number := p_no;
begin
delete from dept where deptno = v_no;
dbms_output.put_line(chr(10)||'The department id is '||v_no||' has been deleted');
end;
/
Enter value for p_no: 20
old 2: v_no number := p_no;
new 2: v_no number := 20;
declare
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated - child record found
ORA-06512: at line 4
- 由于違反外鍵約束,刪除部門失敗了。但是拋出的錯(cuò)誤不是很好理解
- 我們可以使用EXCEPTION_INIT來(lái)對(duì)這個(gè)錯(cuò)誤進(jìn)行處理,首先我們得知道違反外鍵約束的這個(gè)Oracle錯(cuò)誤代碼“ORA-02292”
- 使用EXCEPTION_INIT
declare
v_no number := p_no;
e_dept_exist exception;
pragma exception_init(e_dept_exist,-02292);
begin
delete from dept where deptno = v_no;
dbms_output.put_line(chr(10)||'The department id is '||v_no||' has been deleted');
exception
when e_dept_exist then
dbms_output.put_line(chr(10)||'There are some employees in this deptartment, if you want delete this deptartment ,please delete these employees in the department first.');
end;
/
Enter value for p_no: 20
old 2: v_no number := p_no;
new 2: v_no number := 20;
There are some employees in this deptartment, if you want delete this deptartment ,please delete these employees in the department first.
PL/SQL procedure successfully completed.
- 這下拋出的錯(cuò)誤就容易理解多了。首先我們定義了一個(gè)名為e_dept_exist的異常,然后將這個(gè)異常與Oracle錯(cuò)誤代碼 -02292 進(jìn)行關(guān)聯(lián)。當(dāng)程序執(zhí)行報(bào)錯(cuò)時(shí)進(jìn)入異常處理部分,在這里我們重新給這個(gè)錯(cuò)誤定義了錯(cuò)誤消息。
3,SQLCODE 和 SQLERRM
- 在異常處理中,當(dāng)異常的名稱未知時(shí)(比如上面1中RAISE_APPLICATION_ERROR),都可以使用others來(lái)進(jìn)行異常的捕獲處理;
- 由于others所捕獲的異常是未知的(也可以是已知的,但是在程序中沒有將其枚舉出來(lái)),因此需要使用Oracle提供的兩個(gè)內(nèi)置函數(shù)SQLCODE、SQLERRM來(lái)針對(duì)others的異常進(jìn)行處理:
- SQLCODE 會(huì)返回Oracle的錯(cuò)誤編號(hào)
- SQLERRM,返回錯(cuò)誤的消息
- 示例1,處理Oracle系統(tǒng)返回的錯(cuò)誤:
declare
v_no number := p_no;
error_code number;
error_msg varchar2(500);
begin
delete from dept where deptno = v_no;
dbms_output.put_line(chr(10)||'The department id is '||v_no||' has been deleted');
exception
when others then
error_code := sqlcode;
error_msg := sqlerrm;
dbms_output.put_line(chr(10)||'Error code is: '||error_code);
dbms_output.put_line(chr(10)||'Error message is: '||error_msg);
end;
Enter value for p_no: 10
old 2: v_no number := p_no;
new 2: v_no number := 10;
Error code is: -2292
Error message is: ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated - child record found
PL/SQL procedure successfully completed.
- 請(qǐng)注意exception異常處理部分,在該部分里面我們用到了聲明部分定義的兩個(gè)變量,error_code用來(lái)存儲(chǔ)SQLCODE,error_msg用來(lái)存儲(chǔ)SQLERRM。然后將兩個(gè)變量值打印出來(lái)。
- 示例2,處理用戶自定義的異常:
declare
v_id number := p_id;
v_name varchar2(20);
v_sal number;
begin
if v_id > 0 then
select ename,sal into v_name,v_sal from emp where empno = v_id;
dbms_output.put_line(chr(10)||v_name||' '||v_sal);
else
raise_application_error (-20001,'Employee id can not be negative.');
end if;
exception
when NO_DATA_FOUND then
dbms_output.put_line(chr(10)||'There is no such employee id is '||v_id);
when others then
declare
error_code number;
error_msg varchar2(500);
begin
error_code := sqlcode;
error_msg := sqlerrm;
dbms_output.put_line(chr(10)||'Error code is: '||error_code);
dbms_output.put_line(chr(10)||'Error message is: '||error_msg);
end;
end;
/
Enter value for p_id: -90
old 2: v_id number := p_id;
new 2: v_id number := -90;
Error code is: -20001
Error message is: ORA-20001: Employee id can not be negative.
PL/SQL procedure successfully completed.
- 在本代碼中使用了raise_application_error,由于單純的使用raise_application_error,只能使用others進(jìn)行捕獲。在異常處理部分,我們使用了一個(gè)PL/SQL語(yǔ)句塊來(lái)處理這個(gè)錯(cuò)誤,聲明兩個(gè)變量,并將SQLCODE和SQLERRM以字面值賦值的方法給這兩個(gè)變量。
總結(jié)
以上所述是小編給大家介紹的Oracle PL/SQL中異常高級(jí)特性示例解析,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
您可能感興趣的文章:- Oracle基本PLSQL的使用實(shí)例詳解
- 詳解PL/SQL Developer連接本地Oracle 11g 64位數(shù)據(jù)庫(kù)
- win7 64位操作系統(tǒng)中Oracle 11g + plsql安裝教程詳解(圖解)
- Plsql Developer連接Oracle時(shí)出現(xiàn)Could not initialize oci.dll解決方案
- 使用PL/SQL Developer連接Oracle數(shù)據(jù)庫(kù)的方法圖解
- Windows 64位下裝安裝Oracle 11g,PLSQL Developer的配置問(wèn)題,數(shù)據(jù)庫(kù)顯示空白的完美解決方案(圖文教程)
- PL/SQL遠(yuǎn)程備份和恢復(fù)Oracle數(shù)據(jù)庫(kù)
- Oracle客戶端與plsql查詢數(shù)據(jù)亂碼修改成中文的快速解決方法