1、异常的申明:

1、语法如下:

exception_name EXCEPTION;

2、异常名称与错误代码绑定


使用编译指示 PRAGMA EXCEPTION_INIT 将异常名称与 一个 Oracle错误绑定,语法为:


PRAGMA EXCEPTION_INIT(exception_name,error_code)



其中, error_code 为错误代码,是一个负的 5 位数, 如-02292 。其中 -20999~-20000 为用户定义错误的保留号。



如“违反唯一约束”代码为“00001”

pymysql异常捕获 plsql捕获所有异常的关键字_pymysql异常捕获

2、异常捕获:

语法如下:

EXCEPTION 
WHEN ex_name_1 
    THEN statements_1
WHEN ex_name_2 OR ex_name_3
     THEN statements_2 
WHEN OTHERS 
     THEN statements_n;

END;


        其中,ex_name_n为异常的名称,而statements_n为对应异常发生时的处理语句。当PL/SQL块执行部分发生错误时,抛出异常,执行部分停止运行,程序流程转移到异常处理部分。如果异常名称为ex_name_1,则执行statements_1;如果异常名称为ex_name_2或ex_name_3,则执行statements_2;否则将执行statements_3。



进行异常捕获时需要注意下列事项:


一个异常处理器可以捕获多个异常,只需在WHEN子句 中用OR连接即可。


一个异常只能被一个异常处理器捕获,并进行处理。



OTHERS异常处理器


        OTHERS异常处理器是一个特殊的异常处理器,可以捕获所有错误抛出的异常。通常,OTHERS异常处理器总是作为异 常处理部分的最后一个异常处理器,负责处理那些没有被其他 异常处理器捕获的异常。



        虽然OTHERS异常处理器可以捕获各种异常,但并不返回 相关错误信息,无法判断到底是哪个错误产生了异常。为此, PL/SQL提供了SQLCODE和SQLERRM两个函数来获取错误相 关信息。



SQLCODE

        在异常处理器中调用SQLCODE函数时,将返回当前异常 处理器捕获的异常对应的错误代码。如果当前捕获的异常 是“NO_DATA_FOUND”,SQLCODE函数的返回值为100;如 果是用户定义异常,则SQLCODE函数的返回值为1,或者是使 用EXCEPTION_INIT时为用户定义异常绑定的代码。 如果在异常处理器外部调用SQLCODE函数,则返回值为 0。

SQLERRM



SQLERRM根据特定的错误代码返回错误的描述信息,最 大长度为512字节。调用形式为:



SQLERRM[(error_code)]

其中,参数error_code为错误代码。根据参数值不同, SQLERRM函数有如下返回值。 

1、不带参数的SQLERRM函数只在异常处理器内部有用,返 回当前SQLCODE函数返回的错误代码对应的错误描述。 
2、如果在异常处理器外部使用无参数的SQLERRM函数或函 数参数为0,则函数返回信息为“ORA-0000:normal, successful completion”。 
3、如果参数error_code值为100,函数返回值为“ORA- 01403”。·如果参数error_code值为非100的正数,函数返回值的形式为:“-error_code:non-ORACLE exception”。 
4、如果参数error_code值为一个负数,并与Oracle的某个错 误代码相同,函数返回相应的Oracle错误描述。 
5、如果参数error_code值是一个负数,但没有相应的Oracle 错误代码,则函数返回值的形式为:“ORA-error_code: Message error_code not found;product=RDBMS; facility=ORA”。

如以下程序:

-- Created on  by Hj 
declare 
  test number ;
  e_test exception;--申明异常
  PRAGMA EXCEPTION_INIT(e_test,-2292);
  i integer;
begin
   dbms_output.put_line('SQLERRM:'||SQLERRM);
  dbms_output.put_line('SQLERRM(0):'||SQLERRM(0));
   dbms_output.put_line('SQLERRM(+100):'||SQLERRM(100));
   dbms_output.put_line('SQLERRM(+200):'||SQLERRM (200));
   dbms_output.put_line('SQLERRM(-6511):'||SQLERRM(-6511)) ;
   dbms_output.put_line('SQLERRM(-50000):'||SQLERRM(-50000));
  
end;

输出结果如下:

pymysql异常捕获 plsql捕获所有异常的关键字_pymysql异常捕获_02



需要注意的是 ,不能在 SQL 语句中直接调用 SQLCODE 函数和SQLERRM函数,可以先将这两个函数的返回值赋予局部变量,然后在SQL语句中使用局部变量。也可以结合dbms_utility.format_error_backtrace()函数查看存储过程详细报错在哪一行,类似于java中e.printStackTrace();


3、抛出异常

        由于系统可以自动识别Oracle内部错误,因此当Oracle错 误产生时系统会隐式抛出与之对应的内部定义异常或预定义异 常。但是,系统无法识别用户定义错误,因此当用户定义错误 产生时,需要用户显式抛出与之对应的异常。对于内部定义异 常或预定义异常,用户也可以根据需要显式抛出。 显式抛出异常使用RAISE语句,语法为:

RAISE [exception];

4、案例

-- Created on  by Hj 
declare 
  v_code NUMBER(6);
  v_text VARCHAR2(200);
  test number ;
  e_test exception;--申明异常
  PRAGMA EXCEPTION_INIT(e_test,-2292);--ORA-02292 违反完整约束条件、已找到子记录
  i integer;
begin
   i:=0;
   if i<=0 then
     raise e_test; --抛出异常
     end if ;
  test:=9/i;
  exception  --捕获异常
    when e_test then
       dbms_output.put_line('输入除数为0错误');
         begin
           i:=0;
          test:=9/i;
          exception  --捕获异常
            when others then
              v_code:=SQLCODE;
              v_text:=SQLERRM;
              dbms_output.put_line('错误代码为'||v_code||'错误信息为'||v_text);

      end;
  
end;

输出结果如下:

pymysql异常捕获 plsql捕获所有异常的关键字_sql_03