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;

createorreplaceprocedurePROC_SUNHONGBO_MONCHNL(timvarchar2)is

timestvarchar(8);

timdayvarchar(33);

sqlsqlvarchar(6666);

no_resultEXCEPTION;

begin

Commit;

selectto_char(sysdate;yyyymmddHH24miss,)timaintotimdayfromdual;

selectto_char(add_months(sysdate,-l),'yyyymm')monintotimestfromdual;

selecttimmonintotimestfromdual;

executeimmediate'deletereport.wo_sunhongbo_chnlwheremon='||tim;

Commit;

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

BEGIN

executeimmediate'altertableshiywll.t_myaddreal_charge'||tim||1varchar2(GG),;

EXCEPTION

WHENno_resultTHEN

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

WHENOTHERSTHEN

DBMSJDUTPUT.PUTJJNEC你的數(shù)據(jù)更新語句!已經(jīng)存在該列1:,||tim);

END;

executeimmediate'updateshiywll.t_mysetreal_charge'||tim11'=null,;

Commit;

Commit;

dbms_output.put_line('timest:|||timest||';tim:|||tim||';timest:|||sqlsql);

Commit;

endPROC_SUNHONGBO_MONCHNL;

Commit;

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

1.1異常處理概念

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

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

1.1.3用戶自定義的異常處理

1.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運行錯誤或用戶定義條件(不一寫是錯誤),

都可以。當然了,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)錯誤

即其他標準的ORACLE錯誤。對這種異常情況的處理,需要用戶在程序中定義,然后由

ORACLE自動將其引發(fā)。

3.用戶定義(User_define)錯誤

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

程序中定義,然后顯式地在程序中將其引發(fā)。

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

EXCEPTION

WHENfirst_exceptionTHEN<codetohandlefirstexception>

WHENsecond_exceptionTHEN〈codetohandlesecondexception>

WHENOTHERSTHEN<codetohandleothersexception>

END;

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

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

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

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

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

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

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

ORA-1001Invalid-CURSOR試圖使用一個無效的游標

ORA-1012Not-logged-on沒有連接到ORACLE

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

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

ORA-1422Too_mary_rowsSELECTIFJTO返回多行

ORA-1476Zero-divide試圖被零除

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

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

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

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

ORA-6504Rowtype-mismatch宿主游標變量號PL/SQL變量有不兼容行類型

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

ORA-6530Access-INTO-null試圖為null對象的屬性賦值

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

個nullpl/sql表上或varray上

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

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

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

并對其完成相應(yīng)的異常錯誤處理即可。

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

DECLARE

v_empnoemployees.employee_id%TYPE:=Sempno;

v_salemployees.salary%TYPE;

BEGIN

SELECTsalaryINTOv_salFROMemployeesWHER3employee_id=v_empno;

IFv_sal<=1500THEN

UPDATEemployeesSETsalary=salary+LOOWHEREemployee_id=v_err1pno;

DBMS_OUTPUT.PUT_L工編碼為」Iv_empno||,員工工資已更新!,);

ELSE

DRMS_OUTPUT.PUT_L工NEL編碼為,||vampnol|,員工工資已經(jīng)超過規(guī)定值”);

ENDIF;

EXCEPTION

WHENNO_DATA_FOUNDTHEN

DBMS_OUTPUT.PUT_L:CNE(,數(shù)據(jù)庫中沒有編碼為,|Iv_empnoII'的員工');

WHENTOO_MANY_ROWSTHEN

DBMS_OUTPUT.PUT_LINE(,程序運行錯誤!請使用游標1);

WHENOTHERSTHEN

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

END;

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

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

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

〈異常情況〉EXCEPTION;

2.將其定義好的異常情況,與標準的ORACLE錯誤聯(lián)系起來,使用EXCEPTIONJNIT語

句:

PRAGMAEXCEPTIONINITY異常情況〉,(錯誤代碼>);

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

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

11

INSERTINTOdepartmentsVALUES(50,'FINANCEz,CHICAGO);

DECLARE

v_deptnodepartments.department_id%TYPE:=&deptno;

deptno_remainingEXCEPTION;

PRAGMAEXCEPTION_INIT(deptno_remaining,-2292);

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

BEGIN

DELETEFROMdepartmentsWHEREdepartment_id=v_deptno;

EXCEPTION

WHENdeptno_remainingTHEN

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

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODEII'——1I|SQLERRM);

END;

1.L3用戶自定義的異常處理

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

過顯式使用RAISE語句來觸發(fā)。當引發(fā)一個異常錯誤時,控制就轉(zhuǎn)向到EXCEPTION塊

異常錯誤部分,執(zhí)行錯誤處理代碼。

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

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

〈異常情況》EXCEPTION;

2.RAISEv異常情況》:

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_L:INE「你的數(shù)據(jù)更新語句失敗了”);

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODEII'——'IISQLERRM);

END;

1.1.4用戶定義的異常處理

調(diào)用DBMS_STANDARD(ORACLE提供的包)包所定義的RAISE_APPLICATION_ERROR

過程,可以重新定義異常錯誤消息,它為應(yīng)用程序提供了一種與ORACLE交互的方法。

RAISE_APPLICATION_ERROR的語法如下:

RAISE_APPLICATION_ERROR(error_numberrerror_message,[keep_errors]);

這里的error_number是從一20,000至i]-20,999之間的參數(shù),

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

keep_errors為可選,如果keep_errors二TRUE,則新錯誤將被添力【倒已經(jīng)弓I發(fā)的錯

誤列表中。如果keep_er「o「s二FALSE(缺?。?則新錯誤將替換當前的錯誤列表。

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

-20992號錯誤,分別處理參數(shù)為空和非法部門代碼兩種錯誤:

CREATETABLEerrlog(

ErrcodeNUMBER,

ErrtextCHAR(40));

CREATEORREPLACEFUNCTIONget_salary(p_deptnoNUMBER)

RETURNNUMBER

AS

vsalNUMBER;

BEGIN

IFp_deptnoISNULLTHEN

RAISE_APPLICATION_ERROR(-20991,'部門彳弋碼為空,);

ELSIFp_deptno<0THEN

RAISE_APPLICATION_ERROR(20992,,無效的部門代碼

ELSE

SELECTSUM(employees.salary)INTOv_salFROMemployees

WHEREemployees.department_id=p_deptno;

RETURNv_sal;

ENDIF;

END;

DECLARE

v_salaryNUMBER(7Z2);

V_sqlcodeNUMBER;

V_sqlerrVARCHAR2(512);

Null_deptnoEXCEPTION;

Invalid_deptnoEXCEPTION;

PRAGMAEXCEPTION_INIT(null_deptnoz-20991);

PRAGMAEXCEPTION_INIT(invalid_deptnoz-20992);

BEGIN

V_salary:=get_salary(10);

DBMSOUTPUT.PUTLINEr10號部門工資:'IITOCHAR(V_salary));

BEGIN

V_salary:=get_salary(-10);

EXCEPTION

WHENinvalid_deptnoTHEN

V_sqlcode:=SQLCODE;

V_sqlerr:=SQLERRM;

INSERTINTOerrlog(errcode,errtext)

VALUES(v_sqlcode,v_sqlerr);

COMMIT;

ENDinnerl;

V_salary:=get_salary(20);

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

BEGIN

V_sa1ary:=gAt._5;a1ary(NUT.T.);

ENDinner2;

V_salary:=get_salary(30);

DBMS_OUTPUT.PUT_LINE(1部門號為30的工資為:'IITO_CHAR(Vsalary));

EXCEPTION

WHENnull_deptnoTHEN

V_sqlcode:=SQLCODE;

Vsqlerr:-SQLERRM;

INSERTINTOerrlog(errcode,errtext)VALUES(v_sqlcodezv_sqlerr);

COMMIT;

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||'——|||SQLERRM);

ENDouter;

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

錄插入:

CREATEORREPLACETRIGGERtr_insert_emp

BEFOREINSERTONemployees

FOREACHROW

BEGIN

IF:new.first_nameISNULLOR:new.last_nameisnullTHEN

RAISE_APPLICATION_ERROR(-20000,1Employeemusthaveaname.');

ENDIF;

END;

1.2異常錯誤傳播

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

的異常錯誤也不一樣。

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

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

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

含塊。

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

然后對該包含塊執(zhí)行步驟1)。

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

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

塊。比如在有如下的PL/SQL程序:

?

DECLARE

namevarchar2(12):=*EricHu';

其它語句

BEGIN

其它語句

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

例子中,由于Abcrumber(3)='abc';出錯,盡管在EXCEPTION中說明了

WHENOTHERSTHEN語句,但WHENOTHERSTHEN也不會被執(zhí)行。但是如果在該

錯誤語句塊的外部有一個異常錯誤,則該錯誤能被抓住,如:

BEGIN

DECLARE

namevarchar2(12):=1EricHu';

其它語句

BEGIN

其它語句

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

EXCEPTION

WHENOTHERSTHEN

其它語句

END;

1-3異常錯誤處理編程

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

理,則在程序運行出錯時,程序就被終止,并且也不提示任何信息。下面是使用系統(tǒng)提供的

異常來編程的例子。

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

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

用SQLERRM和SUBSTR函數(shù)一起得到錯誤提示信息,方便進行錯誤,特別是如果

WHENOTHERS異常處理器時更為方便。

SQLCODE返回遇到的Oracle錯誤號,

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

如:SQLCODE=-100eSQLERRM=,no_data_found'

SQLCODE=0eSQLERRM='normal,successfualcompletion'

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

CREATETABLEerrors(errnumNUMBER(4)zerrmsgVARCHAR2(100));

DECLARE

err_msgVARCHAR2(100);

BEGIN

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

FORerr_numIN-100..0LOOP

err_msg:=SQLERRM(err_num);

TNSF.RTTNTOarrcrsVAT.OES(Arr_numzprr_msg);

ENDLOOP;

END;

DROPTABLEerrors;

例7.查詢ORACLE錯誤代碼;

BEGIN

INSERTINTOemployees(employee_id,firstname,lastname,hiredate,departm

ent_id)

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

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

INSERTINTOemployees(employee_id,firstname,lastname,hiredate,departm

ent_id)

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

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

EXCEPTION

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODE||'——'||SQLERRM);

END;

A

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

DECLARE

empno_remainingEXCEPTION;

PRAGMAEXCEPTION_INIT(empno_remainingz-1);

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

BEGIN

INSERTINTOemployees(employeeid,firstname,lastname,hiredate,departm

ent_id)

1

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

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

INSERTINTOemployees(employee_id,firstname,lastname,hiredate,departm

ent_id)

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

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

EXCEPTION

WHENempno_remainingTHEN

DBMS_OUTPUT.PUT_L3:NE(,違反數(shù)據(jù)完整性約束!,);

WHENOTHERSTHEN

DBMS_OUTPUT.PUT_LINE(SQLCODEI|'——'||SQLERRM);

END;

Oracle存儲過程異常處理

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

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

BEGIN

SELECT...

-checkfor*nodatafound5error

SELECT...

--checkfor!nodatafound,error

SELECT...

-checkfor'nodatafound,error

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

差,使用異常,可以方便處理錯誤,而且異常處理程序與正常的事務(wù)邏

輯分開,提高了可讀性,如

BEGIN

SELECT...

SELECT...

SELECT...

EXCEPTION

WHENNO_DATA_FOUNDTHEN-catchesall'nodatafound,

errors

2、異常的分類

有兩種類型的異常,--種為內(nèi)部異常,一種為用戶自定義異常,內(nèi)

部異常是執(zhí)行期間返回到PL/SQL塊的ORACLE錯誤或由PL/SQL代

碼的某操作引起的錯誤,如除數(shù)為零或內(nèi)存溢出的情況。用戶自定義異

常由開發(fā)者顯示定義,在PL/SQL塊中傳遞信息以控制對于應(yī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

no_data_foundora-01403+100

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

too_many_rowsora-01422-1422selectinto語句符合條

件的記錄有多條返回

dup_val_on_indexora-00001-1對于數(shù)據(jù)庫表中的某一

列,該列己經(jīng)被限制為唯一索引,程序試圖存儲兩個重復(fù)的值

value_errorora-06502-6502在轉(zhuǎn)換字符類型,截取或長

度受限時,會發(fā)生該異常,如一個字符分配給一個變量,而該變量聲明

的長度比該字符短,就會引發(fā)該異常

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

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

case_not_foundora-06592-6530對于選擇case語句,

沒有與之相匹配的條件,同時,也沒有else語句捕獲其他的條件

cursor_already_openora-06511-6511程序試圖打開一

個已經(jīng)打開的游標

timeout_on_resourceora-00051-51系統(tǒng)在等待某一資

源,時間超時

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

PRAGMAEXCEPTIONJNIT。PRAGMA由編譯器控制,或者是對于

編譯器的注釋。PRAGMA在編譯時處理,而不是在運行時處理。

EXCEPTIONJNIT告訴編譯器將異常名與ORACLE錯誤碼結(jié)合起來,

這樣可以通過名字引用任意的內(nèi)部異常,并且可以通過名字為異常編寫

一適當?shù)漠惓L幚砥鳌?/p>

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

PRAGMAEXCEPTION_INIT(exception_name,

-Oracle_error_number);

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

DECLARE

deadlock_detectedEXCEPTION;

PRAGMAEXCEPTION_INIT(deadlock_detected,-60);

BEGIN

SomeoperationthatcausesanORA-00060error

EXCEPTION

WHENdeadlock_detectedTHEN

-handletheerror

END;

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

異常的名字由EXCEPTION關(guān)鍵字引入:

reservedjoanedException

產(chǎn)生異常后,控制傳給了子程序的異常部分,將異常轉(zhuǎn)向各自異常

控制塊,必須在代碼中使用如下的結(jié)構(gòu)處理錯誤:

Exception

Whenexception1then

Sequenceofstatements;

Whenexception2then

Sequenceofstatements;

Whenothersthen

3、異常的拋出

由三種方式拋出異常

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

2.使用RAISE語句

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

當數(shù)據(jù)庫或PL/SQL在運行時發(fā)生錯誤時,一個異常被PL/SQL運

行時引擎自動拋出。異常也可以通過RAISE語句拋出

RAISEexception_name;

顯式拋出異常是程序員處理聲明的異常的習慣用法,但RAISE不

限于聲明了的異常,它可以拋出任何任何異常。例如,你希望用

TIMEOUT_ON_RESOURCE錯誤檢測新的運行時異常處理器,你只需

簡單的在程序中使用下面的語句:

RAISETIMEOUT_ON_RESOUCE;

比如下面一個訂單輸入的例子,若當訂單小于庫存數(shù)量,則拋出異

常,并且捕獲該異常,處理異常

DECLARE

inventory_toojowEXCEPTION;

一其他聲明語句

BEGIN

IForder_rec.qty>inventory_rec.qtyTHEN

RAISEinventory_t°°Jowi

ENDIF

EXCEPTION

WHENinventory_too_lowTHEN

order_rec.staus:='backordered,;

END;

RAISE_APPLICATION_ERROR內(nèi)建函數(shù)用于拋出一個異常并給

異常賦予一個錯誤號以及錯誤信息。自定義異常的缺省錯誤號是+1,缺

省信息是User_Defined_ExceptionoRAISE_APPLICATION_ERROR

函數(shù)能夠在pl/sql程序塊的執(zhí)行部分和異常部分調(diào)用,顯式拋出帶特殊

錯誤號的命名異常。

Raise_application_error(error_number,message[,true,false]))

錯誤號的范圍是?20,000到?20,999。錯誤信息是文本字符串,最多

為2048字節(jié)。TRUE和FALSE表示是添加(TRUE)進錯誤堆(ERROR

STACK)還是覆蓋(overwrite)錯誤堆(FALSE)。缺省情況下是FALSEo

如下代碼所示:

IFproduct_not_foundTHEN

RAISE_APPLICATION_ERROR(-20123,'lnvaldproductcode'

TRUE);

ENDIF;

4、異常的處理

PL/SQL程序塊的異常部分包含了程序處理錯誤的代碼,當異常被

拋出時,一個異常陷阱就自動發(fā)生,程序控制離開執(zhí)行部分轉(zhuǎn)入異常部

分,一旦程序進入異常部分就不能再回到同一塊的執(zhí)行部分。下面是異

常部分的一般語法:

EXCEPTION

WHENexception_nameTHEN

Codeforhandingexception_name

[WHENanother_exceptionTHEN

Codeforhandinganother_exception]

[WHENothersTHEN

codeforhandinganyotherexception.]

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

WHENOTHERS子串必須放置在最后面作為缺省處理器處理沒有顯式

處理的異常。當異常發(fā)生時,控制轉(zhuǎn)到異常部分,ORACLE查找當前

異常相應(yīng)的WHEN..THEN語句,捕捉異常,THEN之后的代碼被執(zhí)行,

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

END后面的語句。如果沒有找到相應(yīng)的異常陷阱,那么將執(zhí)行WHEN

OTHERSo在異常部分WHEN子串沒有數(shù)量限制。

EXCEPTION

WHENinventory_too_lowTHEN

order_rec.staus:='backordered,;

replenish_inventory(inventory_nbr=>

inventory_rec.sku,inin_amount=>order_rec.qty-inventory_rec.qty):

WHENdiscontinuedJtemTHEN

-codefordiscontinuedjtemprocessing

WHENzero_divideTHEN

-codeforzero_divide

WHENOTHERSTHEN

-codeforanyotherexception

END;

當異常拋出后,控制無條件轉(zhuǎn)到異常部分,這就意味著控制不能回

到異常發(fā)生的位置,當異常被處理和解決后,控制返回到上一層執(zhí)行部

分的下一條語句。

BEGIN

DECLARE

bad_creditexception;

BEGIN

RAISEbad_credit;

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

EXCEPTION

WHENbad_creditTHEN

dbms_output.put_line('bad_credit');

END;

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

EXCEPTION

WHENOTHERSTHEN

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

■■因為bad_credit已被處理

END;

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

播到上一層塊的異常處理部分。

BEGIN

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

bad_creditexception;

BEGIN

RAISEbad_credit;

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

EXCEPTION

WHENZERO_DIVIDETHEN一不能處理bad_credite異常

dbms_output.put_line('dividebyzeroerror');

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

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

一異常部分

EXCEPTION

WHENOTHERSTHEN

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

END;

5、異常的傳播

沒有處理的異常將沿檢測異常調(diào)用程序傳播到外面,當異常被處理

并解決或到達程序最外層傳播停止。在聲明部分拋出的異常將控制轉(zhuǎn)到

上一層的異常部分。

BEGIN

executablestatements

BEGIN

todayDATE:='SYADATE';-ERRROR

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

dbms_output.putjine(*thislinewillnotexecute');

EXCEPTION

WHENOTHERSTHEN

?一異常不會在這里處理

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

EXCEPTION

WHENOTHERSTHEN

處理異常

END

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

誤。

IRaiseexception;

IRaisepackage.exception;

IRaise;

以上是raise的三種使用方法。第一種用于生成當前程序中定義的異常

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

Declare

Invalidjdexception;

ld_valuesvarchar(2);

Begin

ld_value:=id_for(,smith,);

Ifsubstr(id_value,1,1)!=,x5

Then

Raiseinvalidjd;

Endif;

Exception

Wheninvalidjd

Then

Dbms_output.put_line(,thisisaninvalidid!');

End;

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

declare

employee_id_innumber;

Begin

Selectemployeejdintoemployee_id_infromemployjistwhere

employee_name=&n;

Ifemployee_idjn=0

Then

Raisezero_devided;

Endif;

Exception

Whenzero_devided

Then

Dbms_output.put_line(^wrong!,);

End;

有一些異常是定義在非標準包中的,如UTL_FILE,DBMS_SQL以及

程序員創(chuàng)建的包中異常??梢允褂胷aise的第二種用法來生成異常。

Ifday_overdue(isbn_in,browserjn)>365

Then

Raiseoverdue_pkg.book_isjost

Endif;

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

當前的異常傳到外部程序時。

Exception

Whenno_data_found

Then

Raise;

End;

Pl.sql使用raise_application_error過程來生成一個有具體描述的異

常。當使用這個過程時,當前程序被中止,輸入輸出參數(shù)被置為原先的

值,但任何DML對數(shù)據(jù)庫所做的改動將被保留,可以在之后

用rollback命令回滾。下面是該過程的原型:

Procedureraise_application_error(

Numbinaryjnteger;

Msgvarchar2;

KeeperrorstackBooleandefaultfalse

)

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

上,DBMS_OUPUT和DBMS_DESCRIBLE包使用

了?20005到?20000的數(shù)字);msg是小于2K個字符的描述語,任

何大于2K的字符都將被自動丟棄;keeperrorstack默認為false,是

指清空異常棧,再將當前異常入棧,如果指定true的話就直接將當前

異常壓入棧中。

CREATEORREPLACEPROCEDUREraise_byjanguage

(codejnINPLSJNTEGER)

IS

l_messageerror_table.error_string%TYPE;

BEGIN

SELECTerror_string

INTOl_message

FROMerror_table,v$nls_parametersv

WHEREerror_number=codejn

ANDstringjanguage=v.VALUE

ANDv.parameter=,NLS_LANGUAGE,;

RAISE_APPLICATION_ERROR(codejn,l_message);

END;

ORACL內(nèi)部異常:

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

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

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

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

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

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

ORA-00022無效的會話ID;訪問被拒絕

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

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

ORA-00025無法分配

ORA-00026丟失或無效的會話ID

ORA-00027無法刪去當前會話

ORA-00028您的會話已被刪去

ORA-00029會話不是用戶會話

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

ORA-00031標記要刪去的會話

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

ORA-00033當前的會話具有空的移植口令

ORA-00034無法在當前PL/SQL會話中

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

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

ORA-00037無法轉(zhuǎn)換到屬「不同服務(wù)器組的會話

ORA-00038無法創(chuàng)建會話:服務(wù)器組屬于其它用戶

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

ORA-00051等待資源超時

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

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

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

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

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

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

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

ORA-00059超出DB_FILES的最大值

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

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

ORA-00062無法獲得DML全表鎖定;DML_LOCKS為0

ORA-00063超出LOG_FILES的最大數(shù)

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

ORA-00065FIXED_DATE的初始化失敗

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

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

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

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

ORA-00070命令無效

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

ORA-00072進程""不活動

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

ORA-00074未指定進程

ORA-00075在此例程未找到進程””

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

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

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

ORA-00079未找到變量

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

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

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

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

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

ORA-00085當前調(diào)用不存在

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

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

ORA-00088共享服務(wù)器無法執(zhí)行命令

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

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

ORA-00091LARGE_POOL_SIZE至少必須為

ORA-00092LARGE_POOL_SIZE必須大于LARGE_POOL_MIN_ALLOC

ORA-00093必須介于和之間

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

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

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

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

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

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

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

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

ORA-00104檢測到死鎖;全部公用服務(wù)器已鎖定等待資源

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-00111:由于服務(wù)器數(shù)目限制在,所以沒有啟動所有服務(wù)器

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

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

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

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

ORA-00116:SERVICE_NAMES名過長

ORA-00117:系統(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:空閑公用服務(wù)器終止

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:當前會話與請求的會話不匹配

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

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

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

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

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

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

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

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

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

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

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

ORA-00202控制文件:“

ORA-00203使用錯誤的控制文件

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

ORA-00205標識控制文件出錯,有關(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_SIZE()不匹配

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

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

ORA-00221寫入控制文件出錯

ORA-00222操作將重新使用當前已安裝控制文件的名禰

ORA-00223轉(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標識或打開快照或復(fù)制控制文件時出錯

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

ORA-00236快照操作不允許:掛上的控制文件為備份文件

ORA-00237快照操作不允許:控制文件新近創(chuàng)建

ORA-00238操作將重用屬于數(shù)據(jù)庫一部分的文件名

ORA-00250未啟動存檔器

ORA-00251LOG_ARCHIVE_DUPLEX_DEST不能是與字符串相同的目的地

ORA-00252日志在線程上為空,無法存檔

ORA-00253字符限制在以內(nèi),歸檔目的字符串超出此限制

ORA-00254存檔控制字符串”時出錯

ORA-00255存檔日志(線程,序列#)時出錯

ORA-00256無法翻譯歸檔目的字符串

ORA-00257存檔器錯誤。在釋放之前僅限于內(nèi)部連接

ORA-00258NOARCHIVELOG模式下的人工存檔必須標識日志

ORA-00259日志(打開線程)為當前日志,無法存檔

ORA-00260無法找到聯(lián)機日志序列(線程)

ORA-00261正在存檔或修改日志(線程)

ORA-00262當前日志(關(guān)閉線程)無法切換

ORA-00263線程沒有需要存檔的記錄

ORA-00264不要求恢復(fù)

ORA-00265要求例程恢復(fù),無法設(shè)置ARCHIVELOG模式

ORA-00266需要存檔日志文件名

ORA-00267無需存檔日志文件名

ORA-00268指定的日志文件不存在n

ORA-00269指定的日志文件為線程的一部分(非)

ORA-00270創(chuàng)建存檔日志時出錯

ORA-00271沒有需要存檔的日志

ORA-00272寫存檔日志時出錯

ORA-00273未記錄的直接加載數(shù)據(jù)的介質(zhì)恢復(fù)

ORA-00274非法恢復(fù)選項

ORA-00275已經(jīng)開始介質(zhì)恢復(fù)

ORA-00276CHANGE關(guān)鍵字已指定但未給出更改編號

ORA-00277UNTIL恢復(fù)標志的非法選項

ORA-00278:此恢復(fù)不再需要日志文件,,

ORA-00279:更改(在生成)對于線程是必需的

ORA-00280:更改對于線程是按序列#進行的

ORA-00281不能使用調(diào)度進程執(zhí)行介質(zhì)恢復(fù)

ORA-00282UPI調(diào)用不被支持,請使用ALTERDATABASERECOVER

ORA-00283恢復(fù)會話因錯誤而取消

ORA-00284恢復(fù)會話仍在進行

ORA-00285TIME未作為字符串常數(shù)給出

ORA-00286無可用成員,或成員無有效數(shù)據(jù)

ORA-00287未找到指定的更改編號(在線程中)

ORA-00288要繼續(xù)恢復(fù),請鍵入ALTERDATABASERECOVERCONTINUE

ORA-00289建議:

ORA-00290操作系統(tǒng)出現(xiàn)存檔錯誤。請參閱下面的錯俁

ORA-00291P

溫馨提示

  • 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論