版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、一个实例
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年法律法规考试题库含完整答案(典优)
- 铁路机车装调工岗前技术基础考核试卷含答案
- 吉林省吉林市磐石市2024-2025学年七年级下学期期末考试道德与法制考题及答案
- 碳汇计量评估师安全宣教水平考核试卷含答案
- 浓硝酸工安全专项模拟考核试卷含答案
- 企业数据安全管理规范实践
- 学堂在线雨课堂《唐宋名家词(河南大学)》网课学堂云单元测试考核答案
- 煤矿班组长安全培训
- 体育培训校区管理制度
- 住宅项目工程总承包管理策划(可编辑)
- 小学消防安全工作责任体系
- 2025广西桂林市面向全国高校招聘急需紧缺专业人才147人笔试备考试卷及答案解析(夺冠)
- 家具摆放施工方案
- 楼体亮化维修合同
- 2025年河南省人民法院聘用书记员考试试题及答案
- 二类洞充填课件
- 肾病的危害与防治科普
评论
0/150
提交评论