Oracle-存儲過程exception異常處理大全及實例_第1頁
Oracle-存儲過程exception異常處理大全及實例_第2頁
Oracle-存儲過程exception異常處理大全及實例_第3頁
Oracle-存儲過程exception異常處理大全及實例_第4頁
Oracle-存儲過程exception異常處理大全及實例_第5頁
已閱讀5頁,還剩38頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

一、一個實例

Commit;

createorreplaceprocedurePROCSUNHONGBOMONCHNL(timvarchar2)is

timestvarchar(8);

timdayvarchar(33);

sqlsqlvarchar(6666);

no_resultEXCEPTION;

begin

Commit;

selectto_char(sysdatc,'yyyymmddHU24mi3s1)timaintotimdayfromdual;

selectto_char(add_months(sysda:e,-l),'yyyymm')monintotimestfromdual;

selecttimmonintotimestfromdual;

executeimmediate'deleterepor:.wo_sunhongbo_chnlwhereraon=*|tim;

Commit;

/?I,添加所需要的列realcharge+time,如果有就拋出異常后繼續(xù)執(zhí)行**********/

BEGIN

executeimmediate1altertabicshiywl1.tmyaddreal_charge*||tim|1varchar2(66)1;

EXCEPTION

WHENno.resultTHEN

DBMS_OUTPUT.PUTJJNE('你的數(shù)據(jù)更新語句失敗了!’);

WHENOTHERSTHEN

DBMS_OUTPL'T.PUTJINE('你的數(shù)據(jù)更新語句!已經(jīng)存在該列1:'IItim);

END;

executeimmediate1updateshiywl1.tmysetreal_charge||tim||'=null';

Commit;

Commit;

dbms_output.put_line('timest:'||timestI|';tim:'I|tim||';timest:'|Isqlsql);

Commit;

endPROC_SUNHONGBO_MONCHNL;

/

Commit;

主要內(nèi)容如下:

1.1異常處理概念

1.1.1預(yù)定義的異常處理

1.1.2非預(yù)定義的異常處理

1.1.3用戶自定義的異常處理

I.1.4用戶定義的異常處理

1.2異常錯誤傳播

1.2.1在執(zhí)行局部引發(fā)異常錯誤

1.2.2在聲明局部引發(fā)異常錯誤

1.3異常錯誤處理編程

1.4在PL/SQL中使用SQLCODE,SQLERRM異常處理函數(shù)

即使是寫得最好的PL/SQL程序也會遇到錯誤或未預(yù)料到的事件。一個優(yōu)秀的程序都應(yīng)該能夠正確處理各種出錯

情況,并盡可能從錯誤中恢復(fù)。任何ORACLE錯誤(報告為ORA-xxxxx形式的Oracle錯誤號)、PL/SQL運行錯

誤或用戶定義條件(不一寫是錯誤),都可以。當(dāng)然了,PL/SQL編譯錯誤不能通過PL/SQL異常處理來處理,因

為這些錯誤發(fā)生在PL/SQL程序執(zhí)行之前。

ORACLE提供異常情況(EXCEPTION)和異常處理(EXCEPTIONHANDLER)來實現(xiàn)錯誤處理。

1.1異常處理概念

異常情況處理(EXCEPTION)是用來處理正常執(zhí)行過程中未預(yù)料的事件,程序塊的異常處理預(yù)定義的錯誤和自定義

錯誤,由于PL/SQL程序塊一旦產(chǎn)生異常而沒有指出如何處理時,程序就會自動終止整個程序運行.

有三種類型的異常錯誤:

1.預(yù)定義(Predefined)錯誤

ORACLE預(yù)定義的異常情況大約有24個。對這種異常情況的處理,無需在程序中定義,由ORACLE自動將其

引發(fā)。

2.非預(yù)定義(Predefined)錯誤

即其他標(biāo)準(zhǔn)的ORACLE錯誤。對這種異常情況的處理,需要用戶在程序中定義,然后由ORACLE自動將其引

發(fā)。

3.用戶定義(Usejdefine)錯誤

程序執(zhí)行過程中,出現(xiàn)編程人員認為的非正常情況。對這種異常情況的處理,需要用戶在程序中定義,然后顯

式地在程序中將其引發(fā)。

異常處理局部一般放在PL/SQL程序體的后半部,結(jié)構(gòu)為:

EXCEPTION

WHENfirstexceptionTHEN<codetohandlefirstexception>

WHENsecond_exceptionTHEN<codetohandlesecondexception>

WHENOTHERSTHEN<codetohandleothersexception>

END;

異常處理可以按任意次序排列,但OTHERS必須放在最后.

1.1.1預(yù)定義的異常處理

預(yù)定義說明的局部ORACLE異常錯誤

錯誤號異常錯誤信息名稱說明

ORA-0001Dup_val_on_index違反了唯一性限制

0RA-0051Timeout-on-resource在等待資源時發(fā)生超時

ORA-0061Transaction-backed-out由于發(fā)生死鎖事務(wù)被揪消

ORA-1001Invalid-CURSOR試圖使用一個無效的海標(biāo)

0RA-1012Not-loggcd-on沒有連接到ORACLE

0RA-1017Login-denied無效的用戶名/口令

ORA-1403NodatafoundSELECTINTO沒有找到數(shù)據(jù)

ORA-1422Too_many_rowsSELECTINTO返回多行

ORA-1476Zero-divide試圖被零除

ORA-1722Invalid-NUMBER轉(zhuǎn)換一個數(shù)字失敗

0RA-6500Storage-error內(nèi)存不夠引發(fā)的內(nèi)部錯誤

ORA-6501Program-error內(nèi)部錯誤

ORA-6502Value-error轉(zhuǎn)換或截斷錯誤

ORA-6504Rowtype-mismatch宿主游標(biāo)變量與PL/SQL變量有不兼容行類型

ORA-6511CURSOR-already-OPEN試圖翻開一個已處于翻開狀態(tài)的游標(biāo)

0RA-6n30Ar.cpRs-TNTO-nnl1試圖為null對象的屬性賦侑

ORA-6531Collcction-is-null試圖將Exists以外的桀合(collection)方法應(yīng)用于一

個nullpl/sql表上或varray上

ORA-6532Subscript-outside-1imit對嵌套或vauay索引得引用超出聲明范圍以外

ORA-6533Subscript-beyond-count對嵌套或varray索引得引用大于集合中元素的個數(shù).

對這種異常情況的處理,只需在PL/SQL塊的異常處理局部,直接引用相應(yīng)的異常情況名,并對其完成相應(yīng)的異

常錯誤處理即可。

例1:更新指定員工工資,如工資小于1500,則加100;

DECLARI:

vempnoemployees,employeeidMYPE:=&empno;

v_salemployees.salary%TYPE;

BEGIN

SELECTsalaryINTOv_salI'ROMemployeesWHEREemployee_id=v_empno;

IFv_sal<-1500THEN

UPDATEemployeesSETsalary=salary+100WHEREemp1oyce_id=v_empno;

DBMS_OUTPUT.PUT_LINE『編碼為'11v_empnoII'員工工資巳更新!');

ELSE

DBMS_OUTPUT.PUT_UNE『編碼為'||v_empno|I'員工工資巳經(jīng)超過規(guī)定值!');

ENDIF;

EXCEPTION

WHENNO_DATA_FOUNDTHEN

DBMS_OUTPUT.PUT_LINE('數(shù)據(jù)庫中沒有編碼為'11v_empno||'的員工');

WHENTOOMANYROWSTHEN

DBMS_OUTPUT.PUT_LINE('程序運行錯誤!請使用游標(biāo)');

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||'-一'|ISQLERRM);

END;

1.1.2非預(yù)定義的異常處理

對于這類異常情況的處理,首先必須對非定義的ORACLE錯誤進行定義。步驟如下:

1.在PL/SQL塊的定義局部定義異常情況:

<異常情況)EXCEPTION;

2.籽其定義好的異常情況,與標(biāo)準(zhǔn)的ORACLE錯誤聯(lián)系起來,使用EXCEPTIONJNIT語句:

PRAGMAEXCEPTIONINIT《異常情況》,<錯誤代碼》);

3.在PL/SQL塊的異常情況處理局部對異常情況做出相應(yīng)的處理。

例2:刪除指定部門的記錄信息,以確保該部門沒有員工。

INSERTINTOdepartmentsVALUES(50,'FINANCE','CHICAGO');

DECLARE

v_dcptnodepartments,departmentid%TYPE:=Sdcptno;

d?ptno_i'GmainingEXCEPTION;

PRAGMAEXCEPTIONTNIT(deplnoremaining,-2292);

/*-2292是違反一致性約束的錯誤代碼*/

BEGIN

DELETEFROMdepartmentsWHEREdepartment_id=vdeptno;

EXCEPTION

WHENdcptno_rcmainingTHEN

DBMS_OUTPUT.PUT_LINE('違反數(shù)據(jù)完整性約束!');

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||'--'ISQLERRM);

END:

1.1.3用戶自定義的異常處理

當(dāng)與一個異常錯誤相關(guān)的錯誤出現(xiàn)k,就會隱含觸發(fā)該異常錯誤。用戶定義的異常錯誤是通過顯式使

用RAISE語句來觸發(fā)。當(dāng)引發(fā)一個異常錯誤時,控制就轉(zhuǎn)向到EXCEPTION塊異常錯誤局部,執(zhí)行錯誤處理

代碼。

對于這類異常情況的處理,步驟如下:

1.在PL/SQL塊的定義局部定義異常情況:

<異常情況)EXCEPTION;

2.RAISE<異常情況);

3.在PL/SQL塊的異常情況處理局部對異常情況做出相應(yīng)的處理。

例3:更新指定員工工資,增加100;

DECLARE

v_empnoemployees.employee_id%TYPE:=&empno;

no.resultEXCEPTION;

BEGIN

UPDATEemployeesSETsalary=salary+100WHEREemployee_id=v_empno;

IFSQL%NOTFOUNDTHEN

RAISEno_result;

ENDIF;

EXCEPTION

WHENno_resultTHEN

DBMS_OUTPUT.PUT_L1雁('你的數(shù)據(jù)更新語句失敗了!');

WHENOTHERSTHEN

DRMS.OUTPUT.Pl)T_I.TNF(SQI.CODE|)'——'iISQLERRM):

END;

1.1.4用戶定義的異常處理

調(diào)用DBMSSTANDARD(()RACLE提供的包)包所定義的RAISEAPPLICATIONERROR過程,叮以重新定義異常錯誤消息,

它為應(yīng)用程序提供了一種與ORACLE交互的方法。

RAISE_APPLICATION_ERROR的語法如下:

RAISEAPPLICATIONERROR(errornumber,errormessage,[keeperrors]):

這里的errojnumber是從-20,000到-20,999之間的參數(shù),

errormessage是相應(yīng)的提示信息(<2048字節(jié)),

keep_errors為可選,如果keep_errors=TRUE,則新錯誤將被添加到已經(jīng)引發(fā)的錯誤列表中。如果

keep_errors=FALSE(缺省),則新錯誤將替換當(dāng)前的錯誤列表。

例4:創(chuàng)立一個函數(shù)get_salary,該函數(shù)檢索指定部門的工資總和,其中定義了-20991和-20992號錯誤,分別

處理參數(shù)為空和非法部門代碼兩種錯誤:

CREATETABLEerrlog(

ErrcodeNUMBER,

ErrtextCHAR(40));

CREATEORREPLACEFUNCTIONget_salary(p_deptnoNUMBER)

RETURNNUMBER

AS

v_salNUMBER;

BEGIN

IFp_deptnoISNULLTHEN

RAISEAPPLICATIONERROR(-20991,'部門代碼為空');

ELSIEp_deptno<0THEN

RAISE_APPLTCATION_ERROR(-20992.'無效的部門代碼');

ELSE

SELECTSUM(employees,salary)INTOv_salFROMemployees

WHRREemployees.departmen1_id=p_dcptno:

RETURNv_sal;

ENDTF;

END;

DECLARE

V.salaryNUMBER(7.2);

V_sqlcodeNUMBER;

V_sqlerrVARCHAR2(512);

NulldeptnoEXCEPTION;

Invalid_deptnoEXCEPT!ON;

PRAGMAEXCEPTTON_INTT(nulldeptno,-20991);

PRAGMAEXCEPTION_INIT(invalid_deptno,-20992);

BEGIN

V_salary:=gct_salary(10);

DBMS_OLTPUT.PUT_LINE('1O號部門工資:'TO_CHAR(V_salary));

BEGIN

V_salary:=get_salary(-10);

EXCEPTION

WHENinvalid_deptnoTHEN

V_sqIcodc:=SQLCODE;

V_sqlerr:=SQLERRM;

INSERTINTOcrrlog(crrcodc,errtext)

VALUES(v_sq1code,v_sqlerr);

COMMIT;

ENDinnerl;

V_salary:=get_salary(20);

DBMS_OUTPUT.PUT_LINE('部門號為20的工資為:'【TO_CHAR(V_salary));

BEGIN

V_salary:=get_salary(NULL);

ENDinner2;

V_salary:=get_salary(30);

DBMS_OUTPUT.PUT_LINE('部門號為30的工資為:'|TO_CHAR(V.salary):>;

EXCEPTION

WHENnull_deptnoTHEN

V_sq1code:=SQLCODE;

V_sqlerr:=SQLERRM;

INSERTINTOerrlog(crrcode,errtext)VALUES(vsqlcode,v_sqlcrr);

COMMIT;

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE|'-'1SQLERRM);

ENDouter:

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

CREATEORREPLACETRIGGERtr_insert_emp

BEFOREINSERTONemployees

FOREACHROW

BEGIN

IF:new.first_nameISNULLOR:new.last_nameisnullTHEN

RAISEAPPLICATIONERROR(-20000,'Employeemusthaveaname.');

ENDIF;

END.

1.2異常錯誤傳播

由于異常錯誤可以在聲明局部和執(zhí)行局部以及異常錯誤局部出現(xiàn),因而在不同局部引發(fā)的異常錯誤也不

一樣。

1.2.1在執(zhí)行局部引發(fā)異常錯誤

當(dāng)一個異常錯誤在執(zhí)行局部引發(fā)時,有以下情況:

1如果當(dāng)前塊對該異常錯誤設(shè)置了處理,則執(zhí)行它并成功完成該塊的執(zhí)行,然后控制轉(zhuǎn)給包含塊。

1如果沒有對當(dāng)前塊異常錯誤設(shè)置定義處理器,則通過在包含塊中引發(fā)它來傳播異常錯誤。然后對該包含塊執(zhí)

行步驟Do

1.2.2在聲明局部引發(fā)異常錯誤

如果在聲明局部引起異常情況,即在聲明局部出現(xiàn)錯誤,那么該錯誤就能影響到其它的塊。比方在有如

下的PL/SQL程序:

DECLARE

namevarchar2(12):='EricHir:

其它語句

BEGIN

其它語句

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

例子中,由于Abenumber(3)=Jabc';出錯,盡管在EXCEPTION中說明了WHENOTHERSTHEN語

句,但州IENOTHERSTHEN也不會被執(zhí)行。但是如果在該錯誤語句塊的外部有一個異常錯誤,則該錯誤能被

抓住,如:

BEGIN

DECLARE

namevarchar2(12):='EricHur;

其它語句

BEGIN

其它語句

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

1.3異常錯誤處理編程

在一般的應(yīng)用處理中,建議程序人員要用異常處理,因為如果程序中不聲明任何異常處埋,則在程序運

行出錯時,程序就被終止,并且也不提示任何信息。下面是使用系統(tǒng)提供的異常來編程的例子。

1.4在PL/SQL中使用SQLCODE,SQLERRM異常處理函數(shù)

由于ORACLE的錯信息最大長度是512字節(jié),為了得到完整的錯誤提示信息,我們可用SQLERRM

和SIJRSTR函數(shù)一起得到錯誤提示信息,方便進行錯誤.特別是如果WHENOTHERS異常處理器時更為方便八

SQLCODE返回遇到的Orac1e錯誤號,

SQLERRM返回遇到的Orac1e錯誤信息.

如:SQI£ODE=-1OO6SQLERRM:'no_data_found'

SQLCODE=OeSQLERRM=*normal,successfualcompletion'

例6.將ORACLE錯誤代碼及其信息存入錯誤代碼表

CREATETAB1.Eerrors(errnumNUMBER(4),errmsgVARCIIAR2(100));

DECLARE

crr.msgVARCHAR2(1OO);

BEGIN

/?得到所有ORACLE錯誤信息?/

FORerr_numIN-100..0LOOP

err_msg:=SQLERRM(err_num);

INSERTINTOerrorsVALUES(err_num,err_msg);

ENDLOOP;

END;

DROPTABLEerrors;

例7.查詢ORACLE錯誤代碼;

BEGIN

INSERTINTOemployees(employee_id,first_name,last_name,hire_date,department_id)

VALUES(2222,'Eric','Hu',SYSDATE,20);

DBMS_OUTPUT.PUT_LINE('插入數(shù)據(jù)記錄成功!');

INSERTINTOemp1oyees(emp1oyeeid,firstname,lastname,hiredate,departmentid)

VALUES(2222,'胡‘,‘勇',SYSDATE,20);

DBMSOUTPUT.PLTJINE('插入數(shù)據(jù)記錄成功!');

EXCEPTION

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE|I'——'llSQLERRM);

END;

例8.利用ORACLE錯誤代碼,編寫異常錯誤處理代碼;

DFCI.ARE

empno_remainingEXCEPTION;

PRAGMAEXCEPTION_TNIT(empno_remaining,-1);

/*-1是違反唯一約束條件的錯誤代碼*/

BEGIN

INSERTINTOemployees(cinployee_id,first_namc,1ast_name,hire_datc,department_id)

VALUES(3333,'Eric','Hu',SYSDATE,20);

DBMSOUTPUT.PUTLINE('插入數(shù)據(jù)記錄成功!');

INSERTINTOemployees(employee_id,first_name,last_name,hire_date,department_id)

VALUES(3333,'胡','勇',SYSDATE,20);

DBMS_OUTPUT.PUT_LINE('插入數(shù)據(jù)記錄成功!');

EXCEPTION

WHENempno_remainingTHEN

DBMSOUTPUT.PUTLINE('違反數(shù)據(jù)完整性約束!');

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQI.CODE|I'一一'||SQLERRM);

END;

Oracle存儲過程異常處理

1、異常的優(yōu)點

如果沒有異常,在程序中,應(yīng)當(dāng)檢查每個命令的成功還是失敗,如

BEGIN

SELECT...

-checkfor'nodatafound'error

SELECT...

-checkfor'nodatafound'error

SELECT...

--checkfor'noda:afound,error

這種實現(xiàn)的方法缺點在于錯誤處理沒有與正常處理分開,可讀性差,使用異常,可

以方便處理錯誤,而且異常處理程序與正常的事務(wù)邏輯分開,提高了可讀性,如

BEGIN

SELECT...

SELECT

SELECT...

???

EXCEPTION

WHENNODATAFOUNDTHEN--catchesal1'nodatafound'errors

2、異常的分類

有兩種類型的異常,一種為內(nèi)部異常,一種為用戶自定義異常,內(nèi)部異常是執(zhí)行期

間返回到PL/SQL塊的ORACLE錯誤或由PL/SQL代碼的某操作引起的錯誤,如除數(shù)為零

或內(nèi)存溢出的情況。用戶自定義異常由開發(fā)者顯示定義,在PL/SQL塊中傳遞信息以控

制對于應(yīng)用的錯誤處理。

每當(dāng)PL/SQL違背了ORACLE原則或超越了系統(tǒng)依賴的原則就會隱式的產(chǎn)生內(nèi)部異

常。因為每個ORACLE錯誤都有一個號碼并且在PL/SQL中異常通過名字處理,ORACLE

提供了預(yù)定義的內(nèi)部異常。如SELECTINTO語句不返回行時產(chǎn)生的ORACLE異常

NO_DATA_FOUNDo對于預(yù)定義異常,現(xiàn)將最常用的異常列舉如下:

exceptionoracleerrorsqlcodevaluecondition

nodata_foundora-01403+100selectinto

語句沒有符合條件的記錄返回

too_many_rowsora-01422-1422selectinto語句符合條件的記錄有多條

返回

dup_val_on_indexora-00001T對于數(shù)據(jù)庫表中的某一列,該列已經(jīng)被限

制為唯一索引,程序試圖存儲兩個重復(fù)的值

value_errorora-06502-6502在轉(zhuǎn)換字符類型,截取或長度受限時,會發(fā)

生該異常,如一個字符分配給一個變量,而該變量聲明的長度比該字符短,就會引發(fā)該

異常

storage_errorora-06500-6500內(nèi)存溢出

zero_divideora-01476-1476除數(shù)為零

case_not_foundora-06592-6530對于選擇case語句,沒有與之相匹配的

條件,同時,也沒有else語句捕獲其他的條件

cursor_already_openora-06511-6511程序試圖翻開一個已經(jīng)翻開的游

標(biāo)

timeout_on_resourceora-00051-51系統(tǒng)在等待某一資源,時間超時

如果要處理未命名的內(nèi)部異常,必須使用OTHERS異常處理器或PRAGMA

EXCEPTION_INIT。PRAGMA曰編譯器控制,或者是對于編譯器的注釋。PRAGMA在編譯時

處理,而不是在運行時處理。EXCEPTIONINIT告訴編譯器將異常名與ORACLE錯誤碼結(jié)

合起來,這樣可以通過名字引用任意的內(nèi)部異常,并且可以通過名字為異常編寫一適當(dāng)

的異常處理器。

在子程序中使用EXCEPTIONINIT的語法如下:

PRAGMAEXCEPTIONTNIT(exceptionname,-Oracleerror_number);

在該語法中,異常名是聲明的異常,下例是其用法:

DECLARE

deadlock_dctcctedEXCEPTION;

PRAGMAEXCEPTION_INIT(deadlock_detected,-60);

BEGIN

…一一Someoperationthatcausesan0RA-00060error

EXCEPTION

WHENdeadlockdetectedTHEN

一handletheerror

END;

對于用戶自定義異常,只能在PL/SQL塊中的聲明局部聲明異常,異常的名字由

EXCEPTION關(guān)鍵字引入:

reservedloanedException

產(chǎn)生異常后,控制傳給了子程序的異常局部,將異常轉(zhuǎn)向各自異??刂茐K,必須在

代碼中使用如下的結(jié)構(gòu)處理錯誤:

Exception

Whenexceptionlthen

Sequenceofstatements;

Whenexception?then

Sequenceofstatements;

Whenothersthen

3、異常的拋出

由三種方式拋出異常

1.通過PL/SQL運行射引擎

2.使用RAISE語句

3.調(diào)用RAISE_APPLICATION_ERROR存儲過程

當(dāng)數(shù)據(jù)庫或PL/SQL在運行時發(fā)生錯誤時,一個異常被PL/SQL運行時引擎自動拋出。

異常也可以通過RAISE語句拋出

RAISEexceptionname;

顯式拋出異常是程序員處理聲明的異常的習(xí)慣用法,但RAISE不限于聲明了的異常,

它可以拋出任何任何異常。例如,你希望用TIMEOUTONRESOURCE錯誤檢測新的運行時

異常處理器,你只需簡單的在程序中使用下面的語句:

RAISETIMEOUTON_RESOUCE;

比方下面一個訂單輸入的例子,若當(dāng)訂單小于庫存數(shù)量,則拋出異常,并且捕獲該

異常,處理異常

DECLARE

inventory_too_lowEXCEPTION;

--其他聲明語句

BEGIN

IForderrec.qty>inventoryrec.qtyTHEN

RAISEinventorytoolow;

ENDIF

EXCEPTION

WHENinventory_too_lowTHEN

order_rec.staus:=rbackordered1;

END;

RAISE_APPLICATION_ERROR內(nèi)建函數(shù)用于拋出一個異常并給異常賦予一個錯誤號以

及錯誤信息。自定義異常的缺省錯誤號是+1,缺省信息是UserJ)efined_Exception0

RAISE.APPLICATION_ERROR函數(shù)能夠在pl/sql程序塊的執(zhí)行局部和異常局部調(diào)用,顯式

拋出帶特殊錯誤號的命名異常。

Raiseapplicationerror(errornumber,message[,true,false]))

錯誤號的范圍是-20,000到-20,999。錯誤信息是文本字符串,最多為2048字節(jié)。

TRUE和FALSE表示是添加(TRUE)進錯誤堆(ERRORSTACK)還是覆蓋(overwrite)錯誤堆

(FALSE)o缺省情況下是FALSE。

如下代碼所示:

IFproduct_not_foundTHEN

RAISE_APPLICATION_ERROR(-20123,1Invaldproductcode1TRUE);

ENDIF;

4、異常的處理

PL/SQL程序塊的異常局部包含了程序處理錯誤的代碼,當(dāng)異常被拋出時,一個異常

陷阱就自動發(fā)生,程序控制離開執(zhí)行局部轉(zhuǎn)入異常局部,一旦程序進入異常局部就不能

再回到同一塊的執(zhí)行局部。下面是異常局部的一般語法:

EXCEPTION

WHENexception_nameTHEN

Codeforhandingexceptionname

[WHENanotherexceptionTHEN

CodeforhandinganoLher_exception]

[WHENothersTHEN

codeforhandinganyotherexception.]

用戶必須在獨立的WHEN子串中為每個異常設(shè)計異常處理代碼,WHENOTHERS子串必

須放置在最后面作為缺省處理器處理沒有顯式處理的異常。當(dāng)異常發(fā)生時,控制轉(zhuǎn)到異

常局部,ORACLE查找當(dāng)前異常相應(yīng)的WHEN..THEN語句,捕捉異常,THEN之后的代碼被

執(zhí)行,如果錯誤陷阱代碼只是退出相應(yīng)的嵌套塊,那么程序?qū)⒗^續(xù)執(zhí)行內(nèi)部塊END后面

的語句。如果沒有找到相應(yīng)的異常陷阱,那么將執(zhí)行WHENOTHERS。在異常局部WHEN子

串沒有數(shù)量限制。

EXCEPTION

WHENinventory_too_lowTHEN

ordcr_rcc.staus:-*backorderedr;

replenish_inventory(inventorynbr=>

inventoryrec.sku,minamount二〉orderrec.qty-inventoryrec.qty);

WHENdiscontinueditemTHEN

一一codefordiscontinued_itemprocessing

WHENzero_divideTHEN

一codeforzero_divide

WHENOTHERSTHEN

-codeforanyotherexception

END;

當(dāng)異常拋出后,控制無條件轉(zhuǎn)到異常局部,這就意味著控制不能回到異常發(fā)生的位

置,當(dāng)異常被處理和解決后,控制返回到上一層執(zhí)行局部的下一條語句。

BEGIN

DECLARE

bad_creditexception:

BEGIN

RAISEbadcredit;

一發(fā)生異常,控制轉(zhuǎn)向;

EXCEPTION

WHENbad_creditTHEN

dbms_output.put_line(1bad_credit1);

END;

一bad_crcdit異常處理后,控制轉(zhuǎn)到這里

EXCEPTION

WHENOTHERSTHEN

--控制不會從bad_credit異常轉(zhuǎn)到這里

一因為bad_credit已被處理

END;

當(dāng)異常發(fā)生時,在塊的內(nèi)部沒有該異常處理器時,控制將轉(zhuǎn)到或傳播到上一層塊的

異常處理局部。

BEGIN

DECLARE-—內(nèi)部塊開始

bad_creditexception:

BEGIN

RAISEbadcredit;

一發(fā)生異常,控制轉(zhuǎn)向:

EXCEPTION

WHENZERO_DIVIDETHEN一不能處理bad_credite異常

dbms_output.put_linc(1dividebyzeroerror*);

END一結(jié)束內(nèi)部塊

一控制不能到達這里,因為異常沒有解決;

一異常局部

EXCEPTION

WHENOTHERSTHEN

一由于bad_credit沒有解決,控制將轉(zhuǎn)到這里

END;

5、異常的傳播

沒有處理的異常將沿檢測異常調(diào)用程序傳播到外面,當(dāng)異常被處理并解決或到達程

序最外層傳播停止。在聲明局部拋出的異常將控制轉(zhuǎn)到上一層的異常局部。

BEGIN

executablestatements

BEGIN

todayDATE:='SYADATE';—ERRROR

BEGIN一內(nèi)部塊開始

dbms_output.put_line(rthislinewillnotexecute1);

EXCEPTION

WHENOTHERSTHEN

一異常不會在這里處理

END;—內(nèi)部塊結(jié)束

EXCEPTION

WHENOTHERSTHEN

處理異常

END

處理oracle系統(tǒng)自動生成系統(tǒng)異常外,可以使用raise來手動生成錯誤。

1Raiseexception;

1Raisepackage,exception;

1Raise:

以上是raise的三種使用方法。第一種用于生成當(dāng)前程序中定義的異?;?/p>

在standard中的系統(tǒng)異常。

Declare

Invalid_idexception;

Id_valuesvarchar(2);

Begin

Id_value:=id_for('smith');

Ifsubstr(id_value,1,1)!=,x'

Then

Raiseinvalid_id;

Endif;

Exception

Wheninvalid_id

Then

Dbir.soutput,putline('thisisan

invalidid!’);

End;

這是一個生成自定義異常的例子,當(dāng)然也可以生成系統(tǒng)異常:

declare

cmployee__idinnumber;

Begin

Selectemployee_idintoeir.ployee_id_infromemploy_listwhereemp1oyee_name=&n;

Ifemployee_id_in=0

Then

Raisezerodevided;

Endif;

Exception

Whenzero_devided

Then

Dbir.s_output.put_line('wrong!’);

End;

有一些異常是定義在非標(biāo)準(zhǔn)包中的,如UTL_FILE,DBMS_SQL以及程序員創(chuàng)立的

包中異常??梢允褂胷aise的第二種用法來生成異常。

Ifday_overdue(isbn_in,browser_in)>365

Then

Raiseoverdue_pkg.book_is_lost

Endif;

在最后一種raise的形式中,不帶任何參數(shù)。這種情況只出現(xiàn)在希望將當(dāng)前的異常

傳到外部程序時。

Exception

Whennodatafound

Then

Raise;

End;

Pl.sql使用raise_app1ication_error過程來生成一個有具體描述的異常。當(dāng)使

用這個過程時,當(dāng)前程序被中止,輸入輸出參數(shù)被置為原先的值,但任何DML對數(shù)

據(jù)庫所做的改動將被保存,可以在之后用rollback命令回滾。下面是該過程的原型:

Procedureraiseapplicationerror(

Numbinary.integer;

Msgvarchar2;

Keeperrors:ackBooleandefaultfalse

)

其中num是在-20999到-20000之間的任何數(shù)字(但事實

上,DBMS_OUPUT和DBMS_DESCRIBLE包使用了-20005到-20000的數(shù)

字);msg是小于2K個字符的描述語,任何大于2K的字符都將被自動丟

棄;keeperrorstack默認為false,是指清空異常棧,再將當(dāng)前異常人棧,如

果指定true的話就直接將當(dāng)前異常壓入棧中。

CREATEORREPLACEPROCEDUREraise_by_language(code.inINPLS_INTEGER)

IS

1messageerrortable,errorstrin喻TYPE;

BEGIN

SELECTerror_string

INTO1message

FROMerrortable,v$nls_parametersv

WHEREerror_number=code_in

ANDstring_language=v.VALUE

ANDv.parameter=rNLS_LANGUAGEr;

RAISE_APPLICATION_ERROR(codc_in,l_mcssagc);

END;

ORACL內(nèi)部異常:

ORA-OOOOl:違反唯一約束條件(.)

ORA-00017:請求會話以設(shè)置跟蹤事件

ORA-0D018:超出最大會話數(shù)

ORA-00019:超出最大會話許可數(shù)

ORA-00020:超出最大進程數(shù)()

ORA-00021:會話附屬于其它某些進程;無法轉(zhuǎn)換會話

OR/X-00022:無效的會話1D;訪問被拒絕

ORA-00023:會話引用進程私用內(nèi)存;無法別離會話

ORA-00024:單一進程模式下不允許從多個進程注冊

ORA-00025:無法分配

ORA-00026:喪失或無效的會話ID

ORA-00027:無法刪去當(dāng)前會話

ORA-00028:您的會話己被刪去

ORA-00029:會話不是用戶會話

ORA-00030:用戶會話ID不存在。

ORA-00031:標(biāo)記要刪去的會話

ORA-00032:無效的會話移植口令

ORA-00033:當(dāng)前的會話具有空的移植口令

ORA-00034:無法在當(dāng)前PL/SQL會話中

ORA-00035:LICENSE_MAX_USERS不能小于當(dāng)前用戶數(shù)

ORA-00036:超過遞歸SQL()級的最大值

ORA-00037:無法轉(zhuǎn)換到屬于不同效勞器組的會話

ORA-00038:無法創(chuàng)立會話:效勞器組屬「其它用戶

ORA-00050:獲取入隊時操作系統(tǒng)出錯

ORA-00051:等待資源超時

ORA-00052:超出最大入隊資源數(shù)。

ORA-00053:超出最大入隊數(shù)

ORA-00054:資源正忙,要求指定N0WAIT

ORA-00055:超出DML鎖的最大數(shù)

ORA-00056;對象上的DDL鎖以不兼容模式掛起

ORA-00057:超出臨時表鎖的最大數(shù)

ORA-00058:DB_BLOCK_SIZE必須為才可安裝此數(shù)據(jù)庫(非)

ORA-00059:超出DBFILES的最大值

ORA-00060:等待資源時檢測到死鎖

ORA-00061:另一個例程設(shè)置了不同的DML_LOCKS

(JRA-00062:無法獲得DML全表鎖定;DML_LOCKS為0

ORA-00063:超出LOGFILES的最尤數(shù)

ORA-00064:對象過大以至無法分配在此0/S(,)

ORA-00065:FIXED_DATE的初始化失敗

ORA-00066:LOG_FILES為但需要成為才可兼容

ORA-00067:值對參數(shù)無效;至少必須為

ORA-00068:值對參數(shù)無效,必須在和之間

ORA-00069:無法獲得鎖定--禁用了表鎖定

(JRA-00070:命令無效

ORA-00071:進程號必須介于1和之間

ORA-00072:進程"”不活動

ORA-00073:命令介于和個參數(shù)之間時使用

ORA-00074:未指定進程

()R/\-00075:在此例程未找到進程

ORA-ODO76:未找到轉(zhuǎn)儲

ORA-00077:轉(zhuǎn)儲無效

ORA-00078:無法按名稱轉(zhuǎn)儲變量

ORA-00079:未找到變量

ORA-00080:層次指定的全局區(qū)域無效

ORA-00081:地址范圍[,)不可讀

ORA-00082:的內(nèi)存大小不在有效集合[1],[2],[4]之內(nèi)

ORA-00083:警告:可能損壞映射的SGA

ORA-00084:全局區(qū)域必須為PGA,SGA或UGA

ORA-00085:當(dāng)前調(diào)用不存在

ORA-00086:用戶調(diào)用不存在

ORA-00087:命令無法在遠程例程上執(zhí)行

ORA-00088:共享效勞器無法執(zhí)行命令

ORA-00089:ORADEBUG命令中無效的例程號

()RA-0()090:未能將內(nèi)存分配給群集數(shù)據(jù)庫ORADEBUG命令

ORA-00091:LARGEPOOLSIZE至少必須為

ORA-00092:LARGE_POOL_SIZE必須大于LARGE_POOL_MIN_ALLOC

ORA-00093;必須介于和之訶

ORA-00094:要求整數(shù)值

ORA-00096:值對參數(shù)無效,它必須來自之間

ORA-00097:使用OracleSQL特性不在SQL92級中

ORA-00099:等待資源時發(fā)生超時,可能是PDML死鎖所致

ORA-OOIOO:未找到數(shù)據(jù)

ORA-OOIOI:系統(tǒng)參數(shù)DISPATCHERS的說明無效

ORA-00102:調(diào)度程序無法使用網(wǎng)絡(luò)協(xié)議

ORA-00103:無效的網(wǎng)絡(luò)協(xié)議;供調(diào)度程序備用

ORA-00104:檢測到死鎖;全部公用效勞器已鎖定等待資源

ORA-00105:未配置網(wǎng)絡(luò)協(xié)議的調(diào)度機制

ORA-00106:無法在連接到調(diào)度程序時啟動/關(guān)閉數(shù)據(jù)庫

ORA-00107:無法連接到ORACLE監(jiān)聽器進程

ORA-00108:無法設(shè)置調(diào)度程序以同步進行連接

ORA-OOlll:由于效勞器數(shù)目限制在,所以沒有啟動所有效勞器

ORA-00112:僅能創(chuàng)立多達(最多指定)個調(diào)度程序

ORA-00113:協(xié)議名過長

ORA-00114:缺少系統(tǒng)參數(shù)SERVICE_NAMES的值

ORA-00115:連接被拒絕;調(diào)度程序連接表已滿

ORA-OOH6:SERVICE_NAMES名過長

ORA-OOH7:系統(tǒng)參數(shù)SERVICE_NAMES的值超出范圍

ORA-00118:系統(tǒng)參數(shù)DISPATCHERS的值超出范圍

ORA-00119:系統(tǒng)參數(shù)的說明無效

ORA-00120:未啟用或安裝調(diào)度機制

ORA-00121:在缺少DISPATCHERS的情況下指定了SHARED_SERVERS

ORA-00122:無法初始化網(wǎng)絡(luò)配置

ORA-00123:空閑公用效勞器終止

ORA-00124:在缺少MAX_SHARED_SERVERS的情況下指定了DISPATCHERS

ORA-00125:連接被拒絕;無效的演示文稿

ORA-00126:連接被拒絕;無效的重復(fù)

ORA-00127:調(diào)度進程不存在

ORA-00128:此命令需要調(diào)度進程名

ORA-00129:監(jiān)聽程序地址驗證失敗

ORA-00130:監(jiān)聽程序地址''無效

ORA-00131:網(wǎng)絡(luò)協(xié)議不支持注冊"

ORA-00132:語法錯誤或無法解析的網(wǎng)絡(luò)名稱

ORA-00150:重復(fù)的事務(wù)處理ID

ORA-00151;無效的事務(wù)處理ID

ORA-00152:當(dāng)前會話與請求的會話不匹配

ORA-00153:XA庫中的內(nèi)部錯誤

ORA-00154:事務(wù)處理監(jiān)視器中的協(xié)議錯誤

ORA-00155:無法在全局事務(wù)處理之外執(zhí)行工作

ORA-00160:全局事務(wù)處理長度越出了最大值0

ORA-00161:事務(wù)處理的分支長度非法(允許的最大長度為)

ORA-00162:外部dbid的長度越出了最大值()

ORA-00163:內(nèi)部數(shù)據(jù)庫名長度越出了最大值()

ORA-00164:在分布式事務(wù)處理中不允許獨立的事務(wù)處理

0RA-0D165:不允許對遠程操作進行可移植分布式自治轉(zhuǎn)換

ORA-00200:無法創(chuàng)立控制文件

ORA-00201:控制文件版本與ORACLE版本不兼容

ORA-00202:控制文件:一

OR/X-00203:使用錯誤的控制文件

ORA-00204:讀控制文件時出錯(塊,#塊)

ORA-00205:標(biāo)識控制文件出錯,有關(guān)詳情,請檢查警告日志

ORA-00206:寫控制文件時出錯(塊,#塊)

ORA-00207:控制文件不能用于同一數(shù)據(jù)庫

ORA-00208:控制文件的名稱數(shù)超出限制

ORA-00209:控制文件塊大小不匹配,有關(guān)詳情,請檢查警告日志

ORA-00210:無法翻開指定的控制文件

ORA-00211:控制文件與先前的控制文件不匹配

ORA-00212:塊大小低于要求的最小大?。ㄗ止?jié))

ORA-00213:不能重新使用控制文件;原文件大小為,還需

ORA-00214:控制文件''版本與文件‘‘版本不一致

ORA-00215:必須至少存在一個控制文件

ORA-00216:無法重新調(diào)整從8.0.2移植的控制文件大小

ORA-00217:從9.0.1進行移植無法重新調(diào)整控制文件的大小

ORA-00218:控制文件的塊大小與DB_BLOCK_SIZE0不匹配

ORA-00219:要求的控制文件大小超出了允許的最大值

ORA-00220:第一個例程未安裝控制文件,有關(guān)詳情,請檢查警告日志

ORA-00221:寫入控制文件出錯

ORA-00222:操作將重新使用當(dāng)前已安裝控制文件的名稱

0RA-0D223:轉(zhuǎn)換文件無效或版本不正確

ORA-00224:控制文件重設(shè)大小嘗試使用非法記錄類型()

ORA-00225:控制文件的預(yù)期大小與實際大小不同

ORA-00226:咯用控制文件翻開時不允許進行操作

ORA-00227:控制文件中檢測到損壞的塊:(塊,#塊)

ORA-00228:備用控制文件名長度超出了最大長度

ORA-00229:操作不允許:已掛起快照控制文件入隊

ORA-00230:操作不允許:無法使用快照控制文件入隊

ORA-00231:快照控制文件未命名

ORA-00232:快照控制文件不存在,已損壞或無法讀取

ORA-00233:控制文件副木已損壞或無法讀取

ORA-00234:標(biāo)識或翻開快照或復(fù)制控制文件時出錯

ORA-00235:控制文件固定表因并發(fā)更新而不一致

ORA-00236:快照操作不允許:掛上的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論