Oracle数据库-自定义异常处理
--第一种方式:使用raise_application_error抛出自定义异常 declare i number:=-1; begin if i=-1 then raise_application_error(-20000,'参数值不能为负'); --抛出自定义异常 end if; exception when others then dbms_output.put_line('err_code:'||sqlcode||';err_msg:'||sqlerrm); --进行异常处理 raise; --继续抛出该异常 end; --第二种方式,使用 exception 进行异常的定义 declare i number:=-1; my_err exception; --自定义异常 PRAGMA EXCEPTION_INIT(my_err, -01476); --初始化异常(我理解就是将该异常绑定到某个错误代码上) begin if i=-1 then raise my_err; --抛出自定义异常 end if; exception when my_err then --捕捉自定义异常 dbms_output.put_line('err_code:'||sqlcode||';err_msg:'||sqlerrm); --异常处理 raise; --继续抛出这个自定义异常 when others then --捕捉其它异常 dbms_output.put_line('err_code:'||sqlcode||';err_msg:'||sqlerrm); --异常处理 raise; --继续抛出异常 end; EXCEPTION WHEN l_exit THEN var_o_message := var_o_message; OPEN user_cusor FOR 'SELECT ''' || var_o_message || ''' AS VAR_O_MESSAGE FROM DUAL WHERE ROWNUM=1'; WHEN OTHERS THEN var_o_message := var_o_message || SQLERRM(SQLCODE) || dbms_utility.format_error_backtrace(); OPEN user_cusor FOR 'SELECT ''' || var_o_message || ''' AS VAR_O_MESSAGE FROM DUAL WHERE ROWNUM=1'; END; 第一种方式自定义异常的代码范围为:-20000到-20300 第二种方式的好处是,可以将自定义异常绑定到某上具体的预定义错误代码上, 如ORA-01476: divisor is equal to zero 这样我们就可以捕捉自定义异常而不需要用 others 进行捕捉了.但也不是所有的预定义异常都可以绑定,这个需要使用的时候自己多试试
Oracle内置函数SQLCODE和SQLERRM是特别用在OTHERS处理器中,分别用来返回Oracle的错误代码和错误消息。
OTHERS处理器应该是异常处理块中的最后的异常处理器,因为它是用来捕获除了别的异常处理器处理以外的所有的Oracle异常,所以在程序的最外层使用一个OTHERS处理器的话,将可以确保所有的错误都会被检测到。
在一个内在的异常中,SQLCODE返回Oracle错误的序号,而SQLERRM返回的是相应的错误消息,错误消息首先显示的是错误代码。SQLCODE返回的是负数,除非Oracle的错误为“ORA-01403:NO DATA FOUND”(译:ORA-01403:未找到数据),当Oracle错误为“ORA-01403:NO DATA FOUND”时,其对应的SQLCODE为+100。对于用户自定义的异常,SQLCODE返回的是+1,而SQLERRM返回的是User-Defined Exception。
一个Oracle的错误消息最多只能包含512个字节的错误代码。
如果没有异常被触发,则SQLCODE返回0,SQLERRM返回“ORA-0000:normal, successful completion”。
实例 Exception
when osi_general_error then
when OTHERS THEN
out_ErrorMsg := SUBSTR(SQLERRM,1,100);
out_ErrorNbr := ABS(SQLCODE);
仅仅输出SQLCODE、SQLERRM是不够的!!!dbms_utility.format_error_backtrace()控制台输出如下:
-1:ORA-00001: unique constraint (SCOTT.SYS_C0012353) violated
ORA-06512: at "SCOTT.PROC_INSERT", line 2
ORA-06512: at line 2
ORA-00001: unique constraint (SCOTT.SYS_C0012353) violated
从中可以看出, dbms_utility.format_error_backtrace记录了异常的具体的栈的信息,显示了异常的具体的传递过程,对于我们调试PL/SQL代码来说是很有好处的
可以直接定位到具体异常的位置