版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
一、一個實例
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,如果有就拋出異常后繼續執行**********/
BEGIN
executeimmediate1altertabicshiywl1.tmyaddreal_charge*||tim|1varchar2(66)1;
EXCEPTION
WHENno.resultTHEN
DBMS_OUTPUT.PUTJJNE('你的數據更新語句失敗了!’);
WHENOTHERSTHEN
DBMS_OUTPL'T.PUTJINE('你的數據更新語句!已經存在該列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;
主要內容如下:
1.1異常處理概念
1.1.1預定義的異常處理
1.1.2非預定義的異常處理
1.1.3用戶自定義的異常處理
I.1.4用戶定義的異常處理
1.2異常錯誤傳播
1.2.1在執行局部引發異常錯誤
1.2.2在聲明局部引發異常錯誤
1.3異常錯誤處理編程
1.4在PL/SQL中使用SQLCODE,SQLERRM異常處理函數
即使是寫得最好的PL/SQL程序也會遇到錯誤或未預料到的事件。一個優秀的程序都應該能夠正確處理各種出錯
情況,并盡可能從錯誤中恢復。任何ORACLE錯誤(報告為ORA-xxxxx形式的Oracle錯誤號)、PL/SQL運行錯
誤或用戶定義條件(不一寫是錯誤),都可以。當然了,PL/SQL編譯錯誤不能通過PL/SQL異常處理來處理,因
為這些錯誤發生在PL/SQL程序執行之前。
ORACLE提供異常情況(EXCEPTION)和異常處理(EXCEPTIONHANDLER)來實現錯誤處理。
1.1異常處理概念
異常情況處理(EXCEPTION)是用來處理正常執行過程中未預料的事件,程序塊的異常處理預定義的錯誤和自定義
錯誤,由于PL/SQL程序塊一旦產生異常而沒有指出如何處理時,程序就會自動終止整個程序運行.
有三種類型的異常錯誤:
1.預定義(Predefined)錯誤
ORACLE預定義的異常情況大約有24個。對這種異常情況的處理,無需在程序中定義,由ORACLE自動將其
引發。
2.非預定義(Predefined)錯誤
即其他標準的ORACLE錯誤。對這種異常情況的處理,需要用戶在程序中定義,然后由ORACLE自動將其引
發。
3.用戶定義(Usejdefine)錯誤
程序執行過程中,出現編程人員認為的非正常情況。對這種異常情況的處理,需要用戶在程序中定義,然后顯
式地在程序中將其引發。
異常處理局部一般放在PL/SQL程序體的后半部,結構為:
EXCEPTION
WHENfirstexceptionTHEN<codetohandlefirstexception>
WHENsecond_exceptionTHEN<codetohandlesecondexception>
WHENOTHERSTHEN<codetohandleothersexception>
END;
異常處理可以按任意次序排列,但OTHERS必須放在最后.
1.1.1預定義的異常處理
預定義說明的局部ORACLE異常錯誤
錯誤號異常錯誤信息名稱說明
ORA-0001Dup_val_on_index違反了唯一性限制
0RA-0051Timeout-on-resource在等待資源時發生超時
ORA-0061Transaction-backed-out由于發生死鎖事務被揪消
ORA-1001Invalid-CURSOR試圖使用一個無效的海標
0RA-1012Not-loggcd-on沒有連接到ORACLE
0RA-1017Login-denied無效的用戶名/口令
ORA-1403NodatafoundSELECTINTO沒有找到數據
ORA-1422Too_many_rowsSELECTINTO返回多行
ORA-1476Zero-divide試圖被零除
ORA-1722Invalid-NUMBER轉換一個數字失敗
0RA-6500Storage-error內存不夠引發的內部錯誤
ORA-6501Program-error內部錯誤
ORA-6502Value-error轉換或截斷錯誤
ORA-6504Rowtype-mismatch宿主游標變量與PL/SQL變量有不兼容行類型
ORA-6511CURSOR-already-OPEN試圖翻開一個已處于翻開狀態的游標
0RA-6n30Ar.cpRs-TNTO-nnl1試圖為null對象的屬性賦侑
ORA-6531Collcction-is-null試圖將Exists以外的桀合(collection)方法應用于一
個nullpl/sql表上或varray上
ORA-6532Subscript-outside-1imit對嵌套或vauay索引得引用超出聲明范圍以外
ORA-6533Subscript-beyond-count對嵌套或varray索引得引用大于集合中元素的個數.
對這種異常情況的處理,只需在PL/SQL塊的異常處理局部,直接引用相應的異常情況名,并對其完成相應的異
常錯誤處理即可。
例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'員工工資巳經超過規定值!');
ENDIF;
EXCEPTION
WHENNO_DATA_FOUNDTHEN
DBMS_OUTPUT.PUT_LINE('數據庫中沒有編碼為'11v_empno||'的員工');
WHENTOOMANYROWSTHEN
DBMS_OUTPUT.PUT_LINE('程序運行錯誤!請使用游標');
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'-一'|ISQLERRM);
END;
1.1.2非預定義的異常處理
對于這類異常情況的處理,首先必須對非定義的ORACLE錯誤進行定義。步驟如下:
1.在PL/SQL塊的定義局部定義異常情況:
<異常情況)EXCEPTION;
2.籽其定義好的異常情況,與標準的ORACLE錯誤聯系起來,使用EXCEPTIONJNIT語句:
PRAGMAEXCEPTIONINIT《異常情況》,<錯誤代碼》);
3.在PL/SQL塊的異常情況處理局部對異常情況做出相應的處理。
例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('違反數據完整性約束!');
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'--'ISQLERRM);
END:
1.1.3用戶自定義的異常處理
當與一個異常錯誤相關的錯誤出現k,就會隱含觸發該異常錯誤。用戶定義的異常錯誤是通過顯式使
用RAISE語句來觸發。當引發一個異常錯誤時,控制就轉向到EXCEPTION塊異常錯誤局部,執行錯誤處理
代碼。
對于這類異常情況的處理,步驟如下:
1.在PL/SQL塊的定義局部定義異常情況:
<異常情況)EXCEPTION;
2.RAISE<異常情況);
3.在PL/SQL塊的異常情況處理局部對異常情況做出相應的處理。
例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雁('你的數據更新語句失敗了!');
WHENOTHERSTHEN
DRMS.OUTPUT.Pl)T_I.TNF(SQI.CODE|)'——'iISQLERRM):
END;
1.1.4用戶定義的異常處理
調用DBMSSTANDARD(()RACLE提供的包)包所定義的RAISEAPPLICATIONERROR過程,叮以重新定義異常錯誤消息,
它為應用程序提供了一種與ORACLE交互的方法。
RAISE_APPLICATION_ERROR的語法如下:
RAISEAPPLICATIONERROR(errornumber,errormessage,[keeperrors]):
這里的errojnumber是從-20,000到-20,999之間的參數,
errormessage是相應的提示信息(<2048字節),
keep_errors為可選,如果keep_errors=TRUE,則新錯誤將被添加到已經引發的錯誤列表中。如果
keep_errors=FALSE(缺省),則新錯誤將替換當前的錯誤列表。
例4:創立一個函數get_salary,該函數檢索指定部門的工資總和,其中定義了-20991和-20992號錯誤,分別
處理參數為空和非法部門代碼兩種錯誤:
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:定義觸發器,使用RAISE_APPLICATION_ERROR阻止沒有員工姓名的新員式記錄插入:
CREATEORREPLACETRIGGERtr_insert_emp
BEFOREINSERTONemployees
FOREACHROW
BEGIN
IF:new.first_nameISNULLOR:new.last_nameisnullTHEN
RAISEAPPLICATIONERROR(-20000,'Employeemusthaveaname.');
ENDIF;
END.
1.2異常錯誤傳播
由于異常錯誤可以在聲明局部和執行局部以及異常錯誤局部出現,因而在不同局部引發的異常錯誤也不
一樣。
1.2.1在執行局部引發異常錯誤
當一個異常錯誤在執行局部引發時,有以下情況:
1如果當前塊對該異常錯誤設置了處理,則執行它并成功完成該塊的執行,然后控制轉給包含塊。
1如果沒有對當前塊異常錯誤設置定義處理器,則通過在包含塊中引發它來傳播異常錯誤。然后對該包含塊執
行步驟Do
1.2.2在聲明局部引發異常錯誤
如果在聲明局部引起異常情況,即在聲明局部出現錯誤,那么該錯誤就能影響到其它的塊。比方在有如
下的PL/SQL程序:
DECLARE
namevarchar2(12):='EricHir:
其它語句
BEGIN
其它語句
EXCEPTION
WHENOTHERSTHEN
其它語句
END;
例子中,由于Abenumber(3)=Jabc';出錯,盡管在EXCEPTION中說明了WHENOTHERSTHEN語
句,但州IENOTHERSTHEN也不會被執行。但是如果在該錯誤語句塊的外部有一個異常錯誤,則該錯誤能被
抓住,如:
BEGIN
DECLARE
namevarchar2(12):='EricHur;
其它語句
BEGIN
其它語句
EXCEPTION
WHENOTHERSTHEN
其它語句
END;
EXCEPTION
WHENOTHERSTHEN
其它語句
END;
1.3異常錯誤處理編程
在一般的應用處理中,建議程序人員要用異常處理,因為如果程序中不聲明任何異常處埋,則在程序運
行出錯時,程序就被終止,并且也不提示任何信息。下面是使用系統提供的異常來編程的例子。
1.4在PL/SQL中使用SQLCODE,SQLERRM異常處理函數
由于ORACLE的錯信息最大長度是512字節,為了得到完整的錯誤提示信息,我們可用SQLERRM
和SIJRSTR函數一起得到錯誤提示信息,方便進行錯誤.特別是如果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('插入數據記錄成功!');
INSERTINTOemp1oyees(emp1oyeeid,firstname,lastname,hiredate,departmentid)
VALUES(2222,'胡‘,‘勇',SYSDATE,20);
DBMSOUTPUT.PLTJINE('插入數據記錄成功!');
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('插入數據記錄成功!');
INSERTINTOemployees(employee_id,first_name,last_name,hire_date,department_id)
VALUES(3333,'胡','勇',SYSDATE,20);
DBMS_OUTPUT.PUT_LINE('插入數據記錄成功!');
EXCEPTION
WHENempno_remainingTHEN
DBMSOUTPUT.PUTLINE('違反數據完整性約束!');
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE(SQI.CODE|I'一一'||SQLERRM);
END;
Oracle存儲過程異常處理
1、異常的優點
如果沒有異常,在程序中,應當檢查每個命令的成功還是失敗,如
BEGIN
SELECT...
-checkfor'nodatafound'error
SELECT...
-checkfor'nodatafound'error
SELECT...
--checkfor'noda:afound,error
這種實現的方法缺點在于錯誤處理沒有與正常處理分開,可讀性差,使用異常,可
以方便處理錯誤,而且異常處理程序與正常的事務邏輯分開,提高了可讀性,如
BEGIN
SELECT...
SELECT
SELECT...
???
EXCEPTION
WHENNODATAFOUNDTHEN--catchesal1'nodatafound'errors
2、異常的分類
有兩種類型的異常,一種為內部異常,一種為用戶自定義異常,內部異常是執行期
間返回到PL/SQL塊的ORACLE錯誤或由PL/SQL代碼的某操作引起的錯誤,如除數為零
或內存溢出的情況。用戶自定義異常由開發者顯示定義,在PL/SQL塊中傳遞信息以控
制對于應用的錯誤處理。
每當PL/SQL違背了ORACLE原則或超越了系統依賴的原則就會隱式的產生內部異
常。因為每個ORACLE錯誤都有一個號碼并且在PL/SQL中異常通過名字處理,ORACLE
提供了預定義的內部異常。如SELECTINTO語句不返回行時產生的ORACLE異常
NO_DATA_FOUNDo對于預定義異常,現將最常用的異常列舉如下:
exceptionoracleerrorsqlcodevaluecondition
nodata_foundora-01403+100selectinto
語句沒有符合條件的記錄返回
too_many_rowsora-01422-1422selectinto語句符合條件的記錄有多條
返回
dup_val_on_indexora-00001T對于數據庫表中的某一列,該列已經被限
制為唯一索引,程序試圖存儲兩個重復的值
value_errorora-06502-6502在轉換字符類型,截取或長度受限時,會發
生該異常,如一個字符分配給一個變量,而該變量聲明的長度比該字符短,就會引發該
異常
storage_errorora-06500-6500內存溢出
zero_divideora-01476-1476除數為零
case_not_foundora-06592-6530對于選擇case語句,沒有與之相匹配的
條件,同時,也沒有else語句捕獲其他的條件
cursor_already_openora-06511-6511程序試圖翻開一個已經翻開的游
標
timeout_on_resourceora-00051-51系統在等待某一資源,時間超時
如果要處理未命名的內部異常,必須使用OTHERS異常處理器或PRAGMA
EXCEPTION_INIT。PRAGMA曰編譯器控制,或者是對于編譯器的注釋。PRAGMA在編譯時
處理,而不是在運行時處理。EXCEPTIONINIT告訴編譯器將異常名與ORACLE錯誤碼結
合起來,這樣可以通過名字引用任意的內部異常,并且可以通過名字為異常編寫一適當
的異常處理器。
在子程序中使用EXCEPTIONINIT的語法如下:
PRAGMAEXCEPTIONTNIT(exceptionname,-Oracleerror_number);
在該語法中,異常名是聲明的異常,下例是其用法:
DECLARE
deadlock_dctcctedEXCEPTION;
PRAGMAEXCEPTION_INIT(deadlock_detected,-60);
BEGIN
…一一Someoperationthatcausesan0RA-00060error
EXCEPTION
WHENdeadlockdetectedTHEN
一handletheerror
END;
對于用戶自定義異常,只能在PL/SQL塊中的聲明局部聲明異常,異常的名字由
EXCEPTION關鍵字引入:
reservedloanedException
產生異常后,控制傳給了子程序的異常局部,將異常轉向各自異常控制塊,必須在
代碼中使用如下的結構處理錯誤:
Exception
Whenexceptionlthen
Sequenceofstatements;
Whenexception?then
Sequenceofstatements;
Whenothersthen
3、異常的拋出
由三種方式拋出異常
1.通過PL/SQL運行射引擎
2.使用RAISE語句
3.調用RAISE_APPLICATION_ERROR存儲過程
當數據庫或PL/SQL在運行時發生錯誤時,一個異常被PL/SQL運行時引擎自動拋出。
異常也可以通過RAISE語句拋出
RAISEexceptionname;
顯式拋出異常是程序員處理聲明的異常的習慣用法,但RAISE不限于聲明了的異常,
它可以拋出任何任何異常。例如,你希望用TIMEOUTONRESOURCE錯誤檢測新的運行時
異常處理器,你只需簡單的在程序中使用下面的語句:
RAISETIMEOUTON_RESOUCE;
比方下面一個訂單輸入的例子,若當訂單小于庫存數量,則拋出異常,并且捕獲該
異常,處理異常
DECLARE
inventory_too_lowEXCEPTION;
--其他聲明語句
BEGIN
IForderrec.qty>inventoryrec.qtyTHEN
RAISEinventorytoolow;
ENDIF
EXCEPTION
WHENinventory_too_lowTHEN
order_rec.staus:=rbackordered1;
END;
RAISE_APPLICATION_ERROR內建函數用于拋出一個異常并給異常賦予一個錯誤號以
及錯誤信息。自定義異常的缺省錯誤號是+1,缺省信息是UserJ)efined_Exception0
RAISE.APPLICATION_ERROR函數能夠在pl/sql程序塊的執行局部和異常局部調用,顯式
拋出帶特殊錯誤號的命名異常。
Raiseapplicationerror(errornumber,message[,true,false]))
錯誤號的范圍是-20,000到-20,999。錯誤信息是文本字符串,最多為2048字節。
TRUE和FALSE表示是添加(TRUE)進錯誤堆(ERRORSTACK)還是覆蓋(overwrite)錯誤堆
(FALSE)o缺省情況下是FALSE。
如下代碼所示:
IFproduct_not_foundTHEN
RAISE_APPLICATION_ERROR(-20123,1Invaldproductcode1TRUE);
ENDIF;
4、異常的處理
PL/SQL程序塊的異常局部包含了程序處理錯誤的代碼,當異常被拋出時,一個異常
陷阱就自動發生,程序控制離開執行局部轉入異常局部,一旦程序進入異常局部就不能
再回到同一塊的執行局部。下面是異常局部的一般語法:
EXCEPTION
WHENexception_nameTHEN
Codeforhandingexceptionname
[WHENanotherexceptionTHEN
CodeforhandinganoLher_exception]
[WHENothersTHEN
codeforhandinganyotherexception.]
用戶必須在獨立的WHEN子串中為每個異常設計異常處理代碼,WHENOTHERS子串必
須放置在最后面作為缺省處理器處理沒有顯式處理的異常。當異常發生時,控制轉到異
常局部,ORACLE查找當前異常相應的WHEN..THEN語句,捕捉異常,THEN之后的代碼被
執行,如果錯誤陷阱代碼只是退出相應的嵌套塊,那么程序將繼續執行內部塊END后面
的語句。如果沒有找到相應的異常陷阱,那么將執行WHENOTHERS。在異常局部WHEN子
串沒有數量限制。
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;
當異常拋出后,控制無條件轉到異常局部,這就意味著控制不能回到異常發生的位
置,當異常被處理和解決后,控制返回到上一層執行局部的下一條語句。
BEGIN
DECLARE
bad_creditexception:
BEGIN
RAISEbadcredit;
一發生異常,控制轉向;
EXCEPTION
WHENbad_creditTHEN
dbms_output.put_line(1bad_credit1);
END;
一bad_crcdit異常處理后,控制轉到這里
EXCEPTION
WHENOTHERSTHEN
--控制不會從bad_credit異常轉到這里
一因為bad_credit已被處理
END;
當異常發生時,在塊的內部沒有該異常處理器時,控制將轉到或傳播到上一層塊的
異常處理局部。
BEGIN
DECLARE-—內部塊開始
bad_creditexception:
BEGIN
RAISEbadcredit;
一發生異常,控制轉向:
EXCEPTION
WHENZERO_DIVIDETHEN一不能處理bad_credite異常
dbms_output.put_linc(1dividebyzeroerror*);
END一結束內部塊
一控制不能到達這里,因為異常沒有解決;
一異常局部
EXCEPTION
WHENOTHERSTHEN
一由于bad_credit沒有解決,控制將轉到這里
END;
5、異常的傳播
沒有處理的異常將沿檢測異常調用程序傳播到外面,當異常被處理并解決或到達程
序最外層傳播停止。在聲明局部拋出的異常將控制轉到上一層的異常局部。
BEGIN
executablestatements
BEGIN
todayDATE:='SYADATE';—ERRROR
BEGIN一內部塊開始
dbms_output.put_line(rthislinewillnotexecute1);
EXCEPTION
WHENOTHERSTHEN
一異常不會在這里處理
END;—內部塊結束
EXCEPTION
WHENOTHERSTHEN
處理異常
END
處理oracle系統自動生成系統異常外,可以使用raise來手動生成錯誤。
1Raiseexception;
1Raisepackage,exception;
1Raise:
以上是raise的三種使用方法。第一種用于生成當前程序中定義的異常或
在standard中的系統異常。
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;
這是一個生成自定義異常的例子,當然也可以生成系統異常:
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;
有一些異常是定義在非標準包中的,如UTL_FILE,DBMS_SQL以及程序員創立的
包中異常。可以使用raise的第二種用法來生成異常。
Ifday_overdue(isbn_in,browser_in)>365
Then
Raiseoverdue_pkg.book_is_lost
Endif;
在最后一種raise的形式中,不帶任何參數。這種情況只出現在希望將當前的異常
傳到外部程序時。
Exception
Whennodatafound
Then
Raise;
End;
Pl.sql使用raise_app1ication_error過程來生成一個有具體描述的異常。當使
用這個過程時,當前程序被中止,輸入輸出參數被置為原先的值,但任何DML對數
據庫所做的改動將被保存,可以在之后用rollback命令回滾。下面是該過程的原型:
Procedureraiseapplicationerror(
Numbinary.integer;
Msgvarchar2;
Keeperrors:ackBooleandefaultfalse
)
其中num是在-20999到-20000之間的任何數字(但事實
上,DBMS_OUPUT和DBMS_DESCRIBLE包使用了-20005到-20000的數
字);msg是小于2K個字符的描述語,任何大于2K的字符都將被自動丟
棄;keeperrorstack默認為false,是指清空異常棧,再將當前異常人棧,如
果指定true的話就直接將當前異常壓入棧中。
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內部異常:
ORA-OOOOl:違反唯一約束條件(.)
ORA-00017:請求會話以設置跟蹤事件
ORA-0D018:超出最大會話數
ORA-00019:超出最大會話許可數
ORA-00020:超出最大進程數()
ORA-00021:會話附屬于其它某些進程;無法轉換會話
OR/X-00022:無效的會話1D;訪問被拒絕
ORA-00023:會話引用進程私用內存;無法別離會話
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-00035:LICENSE_MAX_USERS不能小于當前用戶數
ORA-00036:超過遞歸SQL()級的最大值
ORA-00037:無法轉換到屬于不同效勞器組的會話
ORA-00038:無法創立會話:效勞器組屬「其它用戶
ORA-00050:獲取入隊時操作系統出錯
ORA-00051:等待資源超時
ORA-00052:超出最大入隊資源數。
ORA-00053:超出最大入隊數
ORA-00054:資源正忙,要求指定N0WAIT
ORA-00055:超出DML鎖的最大數
ORA-00056;對象上的DDL鎖以不兼容模式掛起
ORA-00057:超出臨時表鎖的最大數
ORA-00058:DB_BLOCK_SIZE必須為才可安裝此數據庫(非)
ORA-00059:超出DBFILES的最大值
ORA-00060:等待資源時檢測到死鎖
ORA-00061:另一個例程設置了不同的DML_LOCKS
(JRA-00062:無法獲得DML全表鎖定;DML_LOCKS為0
ORA-00063:超出LOGFILES的最尤數
ORA-00064:對象過大以至無法分配在此0/S(,)
ORA-00065:FIXED_DATE的初始化失敗
ORA-00066:LOG_FILES為但需要成為才可兼容
ORA-00067:值對參數無效;至少必須為
ORA-00068:值對參數無效,必須在和之間
ORA-00069:無法獲得鎖定--禁用了表鎖定
(JRA-00070:命令無效
ORA-00071:進程號必須介于1和之間
ORA-00072:進程"”不活動
ORA-00073:命令介于和個參數之間時使用
ORA-00074:未指定進程
()R/\-00075:在此例程未找到進程
ORA-ODO76:未找到轉儲
ORA-00077:轉儲無效
ORA-00078:無法按名稱轉儲變量
ORA-00079:未找到變量
ORA-00080:層次指定的全局區域無效
ORA-00081:地址范圍[,)不可讀
ORA-00082:的內存大小不在有效集合[1],[2],[4]之內
ORA-00083:警告:可能損壞映射的SGA
ORA-00084:全局區域必須為PGA,SGA或UGA
ORA-00085:當前調用不存在
ORA-00086:用戶調用不存在
ORA-00087:命令無法在遠程例程上執行
ORA-00088:共享效勞器無法執行命令
ORA-00089:ORADEBUG命令中無效的例程號
()RA-0()090:未能將內存分配給群集數據庫ORADEBUG命令
ORA-00091:LARGEPOOLSIZE至少必須為
ORA-00092:LARGE_POOL_SIZE必須大于LARGE_POOL_MIN_ALLOC
ORA-00093;必須介于和之訶
ORA-00094:要求整數值
ORA-00096:值對參數無效,它必須來自之間
ORA-00097:使用OracleSQL特性不在SQL92級中
ORA-00099:等待資源時發生超時,可能是PDML死鎖所致
ORA-OOIOO:未找到數據
ORA-OOIOI:系統參數DISPATCHERS的說明無效
ORA-00102:調度程序無法使用網絡協議
ORA-00103:無效的網絡協議;供調度程序備用
ORA-00104:檢測到死鎖;全部公用效勞器已鎖定等待資源
ORA-00105:未配置網絡協議的調度機制
ORA-00106:無法在連接到調度程序時啟動/關閉數據庫
ORA-00107:無法連接到ORACLE監聽器進程
ORA-00108:無法設置調度程序以同步進行連接
ORA-OOlll:由于效勞器數目限制在,所以沒有啟動所有效勞器
ORA-00112:僅能創立多達(最多指定)個調度程序
ORA-00113:協議名過長
ORA-00114:缺少系統參數SERVICE_NAMES的值
ORA-00115:連接被拒絕;調度程序連接表已滿
ORA-OOH6:SERVICE_NAMES名過長
ORA-OOH7:系統參數SERVICE_NAMES的值超出范圍
ORA-00118:系統參數DISPATCHERS的值超出范圍
ORA-00119:系統參數的說明無效
ORA-00120:未啟用或安裝調度機制
ORA-00121:在缺少DISPATCHERS的情況下指定了SHARED_SERVERS
ORA-00122:無法初始化網絡配置
ORA-00123:空閑公用效勞器終止
ORA-00124:在缺少MAX_SHARED_SERVERS的情況下指定了DISPATCHERS
ORA-00125:連接被拒絕;無效的演示文稿
ORA-00126:連接被拒絕;無效的重復
ORA-00127:調度進程不存在
ORA-00128:此命令需要調度進程名
ORA-00129:監聽程序地址驗證失敗
ORA-00130:監聽程序地址''無效
ORA-00131:網絡協議不支持注冊"
ORA-00132:語法錯誤或無法解析的網絡名稱
ORA-00150:重復的事務處理ID
ORA-00151;無效的事務處理ID
ORA-00152:當前會話與請求的會話不匹配
ORA-00153:XA庫中的內部錯誤
ORA-00154:事務處理監視器中的協議錯誤
ORA-00155:無法在全局事務處理之外執行工作
ORA-00160:全局事務處理長度越出了最大值0
ORA-00161:事務處理的分支長度非法(允許的最大長度為)
ORA-00162:外部dbid的長度越出了最大值()
ORA-00163:內部數據庫名長度越出了最大值()
ORA-00164:在分布式事務處理中不允許獨立的事務處理
0RA-0D165:不允許對遠程操作進行可移植分布式自治轉換
ORA-00200:無法創立控制文件
ORA-00201:控制文件版本與ORACLE版本不兼容
ORA-00202:控制文件:一
OR/X-00203:使用錯誤的控制文件
ORA-00204:讀控制文件時出錯(塊,#塊)
ORA-00205:標識控制文件出錯,有關詳情,請檢查警告日志
ORA-00206:寫控制文件時出錯(塊,#塊)
ORA-00207:控制文件不能用于同一數據庫
ORA-00208:控制文件的名稱數超出限制
ORA-00209:控制文件塊大小不匹配,有關詳情,請檢查警告日志
ORA-00210:無法翻開指定的控制文件
ORA-00211:控制文件與先前的控制文件不匹配
ORA-00212:塊大小低于要求的最小大小(字節)
ORA-00213:不能重新使用控制文件;原文件大小為,還需
ORA-00214:控制文件''版本與文件‘‘版本不一致
ORA-00215:必須至少存在一個控制文件
ORA-00216:無法重新調整從8.0.2移植的控制文件大小
ORA-00217:從9.0.1進行移植無法重新調整控制文件的大小
ORA-00218:控制文件的塊大小與DB_BLOCK_SIZE0不匹配
ORA-00219:要求的控制文件大小超出了允許的最大值
ORA-00220:第一個例程未安裝控制文件,有關詳情,請檢查警告日志
ORA-00221:寫入控制文件出錯
ORA-00222:操作將重新使用當前已安裝控制文件的名稱
0RA-0D223:轉換文件無效或版本不正確
ORA-00224:控制文件重設大小嘗試使用非法記錄類型()
ORA-00225:控制文件的預期大小與實際大小不同
ORA-00226:咯用控制文件翻開時不允許進行操作
ORA-00227:控制文件中檢測到損壞的塊:(塊,#塊)
ORA-00228:備用控制文件名長度超出了最大長度
ORA-00229:操作不允許:已掛起快照控制文件入隊
ORA-00230:操作不允許:無法使用快照控制文件入隊
ORA-00231:快照控制文件未命名
ORA-00232:快照控制文件不存在,已損壞或無法讀取
ORA-00233:控制文件副木已損壞或無法讀取
ORA-00234:標識或翻開快照或復制控制文件時出錯
ORA-00235:控制文件固定表因并發更新而不一致
ORA-00236:快照操作不允許:掛上的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026宣城單招面試題及答案
- 2026藥學相關面試題及答案
- 2026疫情社區面試題型及答案
- 2026中國智能家居協議標準統一與全屋互聯生態構建
- 2026中國印刷機械行業市場供需分析及工業制造投資評估規劃分析研究報告
- 2026人工智能行業應用領域及商業化研究分析
- 2026汽車尾氣催化轉換行業市場供需分析及投資評估規劃分析研究報告
- 2026人工智能芯片產業鏈分析研究報告機遇與風險白皮書
- 2026石油化工產品行業當前市場供需情況分析及投資價值評估規劃分析研究報告
- 2027屆綿陽市三臺縣數學六年級第一學期期末聯考模擬試題含解析
- 2026中豫數創(河南)科技有限公司社會招聘工作人員73人筆試模擬試題及答案詳解
- 2026年消防員招錄面試備考寶典
- 教育局選調題目及答案
- 中國介入超聲臨床應用指南(2026版)
- 工程一級質量技術交底
- 干細胞介導乙肝病毒清除-洞察與解讀
- 財新智庫 2025中國養老產業研究報告
- 旅游介紹文案
- 2025年1月-12月時事政治歸納總結(備考必背)
- 四川省2025年高職單招職業技能綜合測試(中職類)智能制造類試卷
- 醫院首問負責制課件
評論
0/150
提交評論