PL/SQL异常机制
Exception,一些中文教材译为例外,我认为这种翻译很失水准。Exception大多数的程序语言都这个捕获机制,但基本都是译为异常。为什么在PL/SQL中就搞成“例外”.
一般的PL程序员都这样写异常处理:
Declare ……
Begin ……
Exception
When others
then Raise_application_error(-20000,‘has an error‘||sqlerrm);
End;
ORACLE有提供两个函数来实现捕获异常信息,SQLCODE:错误代码、SQLERRM:错误描述。事实上,上述写法主要是方便,也没有根本性的错误。但PL/SQL与JAVA相似,异常捕获也是有层次的。OTHERS会捕获到ORACLE全部的异常,这对于大型数据库而言,也是会影响到效率的。
实现自定义异常。
Declare
i number:=1;
Cu_ex Exception;
Begin
insert into test_table values(2,22);
这样如果发生自定异常,就不会捕获ORACLE的全部异常了。在PL/SQL如果没有定义异常,那么就相当于JAVA中抛出异常THROWS,抛出的异常由调用该块的PL/SQL程序负责处理。 另外,异常与事务,ORACLE的书上都只说异常是不会中止事务。但拿上面那段代码去测试,就会异常发生时事务是有回滚的。那么是否说明异常不会中止事务的说法不正确的? 再测试下面这段代码,异常就不会中止事务了。
BEGIN
Declare i number:=1;
Cu_ex Exception;
Begin insert into test_table values(2,22);
If (i=1) then Raise Cu_ex;
End if;
DBMS_OUTPUT.put_line('TEST'); commit;
Exception When Cu_ex then Raise_application_error(-20000,'has a customer error'||sqlerrm);
When others then Raise_application_error(-20001,'has an error'||sqlerrm);
End;
EXCEPTION WHEN OTHERS THEN
NULL;
END;
原因:Raise_application_error(-20000,'has a customer error'||sqlerrm)这段语句会再次抛出异常,但在外层块中将这个异常捕获到。所以异常不会传回调用环境,事务也就不会由中止(注意外层块中是null)。
总结:异常一般是不会中止事务的,但如果PL/SQL块将异常抛出,则事务会回传给调用环境,由服务器自动进行事务中止操作。