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代码来说是很有好处的

可以直接定位到具体异常的位置 


原文地址:https://www.cnblogs.com/turnip/p/13705062.html