Oracle异常

 如果没有异常,在程序中,应当检查每个命令的成功还是失败,使用异常,可以方便处理错误,而且异常处理程序与正常的事务逻辑分开,提高了可读性。

  1、异常的优点


  2、异常的分类

  有两种类型的异常,一种为内部异常,一种为用户自定义异常,内部异常是执行期间返回到PL/SQL块的。用户自定义异常由开发者显示定义,在PL/SQL块中传递信息以控制对于应用的错误处理。

  为每个ORACLE错误都有一个号码并且在PL/SQL中异常通过名字处理,ORACLE提供了预定义的内部异常。如SELECT INTO 语句不返回行时产生的ORACLE异常NO_DATA_FOUND。最常用的异常列举如下:

exception oracle error sqlcode value condition
no_data_found ora-01403 +100 select into 语句没有符合条件的记录返回
too_mang_rows  ora-01422  -1422 select into 语句符合条件的记录有多条返回
dup_val_on_index ora-00001 -1 对于数据库表中的某一列,该列已经被限制为唯一索引,程序试图存储两个重复的值
value_error  ora-06502 -6502 在转换字符类型,截取或长度受限时,会发生该异常,如一个字符分配给一个变量,而该变量声明的长度比该字符短,就会引发该异常
storage_error  ora-06500 -6500  内存溢出
zero_divide ora-01476 -1476  除数为零
case_not_found ora-06592 -6530 对于选择case语句,没有与之相匹配的条件,同时,也没有else语句捕获其他的条件
cursor_already_open  ora-06511  -6511 程序试图打开一个已经打开的游标
timeout_on_resource ora-00051  -51 系统在等待某一资源,时间超时

 



3、异常的抛出

  由三种方式抛出异常

  1. 通过PL/SQL运行时引擎

  2. 使用RAISE语句

  3. 调用RAISE_APPLICATION_ERROR存储过程

  当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL运行时引擎自动抛出。异常也可以通过RAISE语句抛出

  RAISE exception_name;

  显式抛出异常是程序员处理声明的异常的习惯用法,但RAISE不限于声明了的异常,它可以抛出任何任何异常。例如,你希望用TIMEOUT_ON_RESOURCE错误检测新的运行时异常处理器,你只需简单的在程序中使用下面的语句:

  RAISE TIMEOUT_ON_RESOUCE;

   RAISE_APPLICATION_ERROR内建函数用于抛出一个异常并给异常赋予一个错误号以及错误信息。自定义异常的缺省错误号是+1,缺省信 息是User_Defined_Exception。RAISE_APPLICATION_ERROR函数能够在pl/sql程序块的执行部分和异常部分 调用,显式抛出带特殊错误号的命名异常。 

Raise_application_error(error_number,message[,true,false]))

  错误号的范围是-20,000到-20,999。错误信息是文本字符串,最多为2048字节。TRUE和FALSE表示是添加(TRUE)进错误堆(ERROR STACK)还是覆盖(overwrite)错误堆(FALSE)。缺省情况下是FALSE。

  如下代码所示:

  IF product_not_found THEN

  RAISE_APPLICATION_ERROR(-20123,'Invald product code' TRUE);

  END IF;

  4、异常的处理

  PL/SQL程序块的异常部分包含了程序处理错误的代码,当异常被抛出时,一个异常陷阱就自动发生,程序控制离开执行部分转入异常部分,一旦程序进入异常部分就不能再回到同一块的执行部分。下面是异常部分的一般语法:

  EXCEPTION

  WHEN exception_name THEN

  Code for handing exception_name

  [WHEN another_exception THEN

  Code for handing another_exception]
        处理异常

  END

   如果要处理未命名的内部异常,必须使用OTHERS异常处理器或PRAGMA EXCEPTION_INIT 。PRAGMA由编译器控制,或者是对于编译器的注释。PRAGMA在编译时处理,而不是在运行时处理。EXCEPTION_INIT告诉编译器将异常名 与ORACLE错误码结合起来,这样可以通过名字引用任意的内部异常,并且可以通过名字为异常编写一适当的异常处理器。

  在子程序中使用EXCEPTION_INIT的语法如下:

  PRAGMA EXCEPTION_INIT(exception_name, -Oracle_error_number);

  在该语法中,异常名是声明的异常,下例是其用法:

DECLARE
       A exception;
       B exception;
       PRAGMA EXCEPTION_INIT(a,
- 1476 );
       t 
number ;
       v 
number ;
BEGIN  
      
      t:
= 100 ;
      v:
= 0 ;
      t:
= t / v;
EXCEPTION
         
WHEN  a  THEN
                  DBMS_OUTPUT.put_line(SQLCODE); 
                  DBMS_OUTPUT.put_line(SQLERRM); 
        
WHEN  OTHERS  THEN
              
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );    
END ;

定义一个自定义异常A,然后用PRAGMA_EXCEPTION_INIT 将 异常 A 与 -1476  (除数为零)号系统内部异常进行帮定,当有出数为零的异常发生后,他就出发异常A。此时的A相当于 zero_divide 异常。


  对于用户自定义异常,只能在PL/SQL块中的声明部分声明异常,异常的名字由EXCEPTION关键字引入:

  reserved_loaned Exception

  产生异常后,控制传给了子程序的异常部分,将异常转向各自异常控制块,必须在代码中使用如下的结构处理错误:

  Exception

  When exception1 then

           Sequence of statements;

  When exception2 then

          Sequence of statements;

  When others then

  5、多个异常触发与捕捉的机制

看6个例子:    

(1)普通的例子

DECLARE
       A exception;
BEGIN  
      RAISE A;
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' EXCEPTION A! ' ); 
         
WHEN  OTHERS  THEN
              
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );     
END ;

 

 输出:EXCEPTION A!

(2)

DECLARE
       A exception;
       B exception;
BEGIN    
     RAISE B;
       
BEGIN  
              RAISE A;
       EXCEPTION
                
WHEN  A  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION A! ' );
                
WHEN  B  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION B! ' );                
       
END ;  
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION A! ' );
         
WHEN  B  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' );   
         
WHEN  OTHERS  THEN
         
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );   
END ;

输出:OUT EXCEPTION B!

异常B触发之后,里层的代码都不会再执行,所以异常A不会触发。

(3)

DECLARE
       A exception;
       B exception;
BEGIN    
       
BEGIN  
              RAISE A;
       EXCEPTION
                
WHEN  A  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION A! ' );
                
WHEN  B  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION B! ' );                
       
END
    RAISE B; 
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION A! ' );
         
WHEN  B  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' ); 
         
WHEN  OTHERS  THEN
         
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );      
END ;

输出:
IN EXCEPTION A!
OUT EXCEPTION B!

在异常A触发之后,异常B因为是在异常A触发的程序块的外层触发的,而异常A在内层也被处理了。所以B也会触发。也就是说,当异常出发之后,如果能及时处理,只能退出本层,不会退出上层。上一层后面的代码还会继续执行。但是,下一层的都不在执行。

(4)

DECLARE
       A exception;
       B exception;
BEGIN    
       
BEGIN  
              RAISE A;
       EXCEPTION
                
WHEN  B  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION B! ' );                
       
END
    RAISE B; 
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION A! ' );
         
WHEN  B  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' );  
         
WHEN  OTHERS  THEN
         
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );     
END ;

输出:OUT EXCEPTION A!

这个有一点难理解。当异常A触发后,没有被马上处理,导致,在被处理之前,所有其他的代码都不会执行,后面的异常B不会被触发,直接到达了下一个Exception。继续处理异常A。

(5)

DECLARE
       A exception;
       B exception;
       C exception;
BEGIN   
   RAISE C; 
       
BEGIN  
              RAISE A;
       EXCEPTION
                
WHEN  B  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION B! ' );                
       
END
    RAISE B; 
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION A! ' );
         
WHEN  B  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' );  
         
WHEN  OTHERS  THEN
         
ROLLBACK ;  
                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );     
END ;

输出:OTHERS EXCEPTION!

异常C触发之后后边的代码不会执行。直接到Exception来处理异常。

(6)

DECLARE
       A exception;
       B exception;
       C exception;
BEGIN   
       
BEGIN  
              RAISE A;
       EXCEPTION
                
WHEN  A  THEN
                  RAISE C;
                
WHEN  B  THEN
                     DBMS_OUTPUT.put_line(
' IN EXCEPTION B! ' );                
       
END
    RAISE B; 
EXCEPTION
         
WHEN  A  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' ); 
         
WHEN  B  THEN
                  DBMS_OUTPUT.put_line(
' OUT EXCEPTION B! ' );  
         
WHEN  OTHERS  THEN
         
ROLLBACK ;  

                    DBMS_OUTPUT.put_line(
' OTHERS EXCEPTION! ' );     
END ;

输出:OTHERS EXCEPTION!

异常A触发之后,又出发了异常C而没有对异常C进行即时的处理。所以异常B不会触发,代码自动转到下面的Exception.
-------------------------------------------------------------------------------------------------------------
1、异常的优点
  
  如果没有 异常,在程序中,应当检查每个命令的成功还是失败,如
  BEGIN
  SELECT ...
  -- check for ’no data found’ error
  SELECT ...
  -- check for ’no data found’ error
  SELECT ...
  -- check for ’no data found’ error
  这种实现的方法缺点在于错误处理没有与正常处理分开,可读性差,使用 异常,可以方便处理错误,而且 异常处理程序与正常的事务逻辑分开,提高了可读性,如
  BEGIN
  SELECT ...
  SELECT ...
  SELECT ...
  ...
  EXCEPTION
  WHEN NO_DATA_FOUND THEN -- catches all ’no data found’ errors
  
   2、异常的分类
  
  有两种类型的 异常,一种为内部 异常,一种为用户自定义 异常,内部 异常是执行期间返回到PL/SQL块的 ORACLE错误或由PL/SQL代码的某操作引起的错误,如除数为零或内存溢出的情况。用户自定义 异常由开发者显示定义,在PL/SQL块中传递信息以控制对于应用的错误处理。
  
  每当PL/SQL违背了 ORACLE原则或超越了系统依赖的原则就会隐式的产生内部 异常。因为每个 ORACLE错误都有一个号码并且在PL/SQL中 异常通过名字处理, ORACLE提供了预定义的内部 异常。如SELECT INTO 语句不返回行时产生的 ORACLE 异常NO_DATA_FOUND。对于预定义 异常,现将最常用的 异常列举如下:
  exception  oracle error  sqlcode value  condition
  no_data_found              ora-01403  +100  select into 语句没有符合条件的记录返回
  too_many_rows  ora-01422  -1422  select into 语句符合条件的记录有多条返回
  dup_val_on_index  ora-00001  -1  对于数据库表中的某一列,该列已经被限制为唯一索引,程序试图存储两个重复的值
  value_error  ora-06502  -6502  在转换字符类型,截取或长度受限时,会发生该 异常,如一个字符分配给一个变量,而该变量声明的长度比该字符短,就会引发该 异常
  storage_error  ora-06500  -6500  内存溢出
  zero_divide  ora-01476  -1476  除数为零
  case_not_found  ora-06592  -6530  对于选择case语句,没有与之相匹配的条件,同时,也没有else语句捕获其他的条件
  cursor_already_open  ora-06511  -6511  程序试图打开一个已经打开的游标
  timeout_on_resource  ora-00051  -51  系统在等待某一资源,时间超时
  
  如果要处理未命名的内部 异常,必须使用OTHERS 异常处理器或PRAGMA EXCEPTION_INIT 。PRAGMA由编译器控制,或者是对于编译器的注释。PRAGMA在编译时处理,而不是在运行时处理。EXCEPTION_INIT告诉编译器将 异常名与 ORACLE错误码结合起来,这样可以通过名字引用任意的内部 异常,并且可以通过名字为 异常编写一适当的 异常处理器。
  
  在子程序中使用EXCEPTION_INIT的语法如下:
  PRAGMA EXCEPTION_INIT(exception_name, - Oracle_error_number);
  
  在该语法中, 异常名是声明的 异常,下例是其用法:
  DECLARE
  deadlock_detected EXCEPTION;
  PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
  BEGIN
  ... -- Some operation that causes an ORA-00060 error
  EXCEPTION
  WHEN deadlock_detected THEN
  -- handle the error
  END;
  
  对于用户自定义 异常,只能在PL/SQL块中的声明部分声明 异常异常的名字由EXCEPTION关键字引入:
  reserved_loaned Exception
  
  产生 异常后,控制传给了子程序的 异常部分,将 异常转向各自 异常控制块,必须在代码中使用如下的结构处理错误:
  Exception
  When exception1 then
  Sequence of statements;
  When exception2 then
  Sequence of statements;
  When others then
  
   3、异常的抛出
  
  由三种方式抛出 异常
  
  1. 通过PL/SQL运行时引擎
  
  2. 使用RAISE语句
  
  3. 调用RAISE_APPLICATION_ERROR存储过程
  
  当数据库或PL/SQL在运行时发生错误时,一个 异常被PL/SQL运行时引擎自动抛出。 异常也可以通过RAISE语句抛出
  RAISE exception_name;
  
  显式抛出 异常是程序员处理声明的 异常的习惯用法,但RAISE不限于声明了的 异常,它可以抛出任何任何 异常。例如,你希望用TIMEOUT_ON_RESOURCE错误检测新的运行时 异常处理器,你只需简单的在程序中使用下面的语句:
  RAISE TIMEOUT_ON_RESOUCE;
  
  比如下面一个订单输入的例子,若当订单小于库存数量,则抛出 异常,并且捕获该 异常,处理 异常
  DECLARE
  inventory_too_low EXCEPTION;
  
  ---其他声明语句
  BEGIN
  IF order_rec.qty>inventory_rec.qty THEN
  RAISE inventory_too_low;
  END IF
  EXCEPTION
  WHEN inventory_too_low THEN
  order_rec.staus:='backordered';
  END;
  
  RAISE_APPLICATION_ERROR内建函数用于抛出一个 异常并给 异常赋予一个错误号以及错误信息。自定义 异常的缺省错误号是+1,缺省信息是User_Defined_Exception。RAISE_APPLICATION_ERROR函数能够在pl/sql程序块的执行部分和 异常部分调用,显式抛出带特殊错误号的命名 异常。  Raise_application_error(error_number,message[,true,false]))
  
  错误号的范围是-20,000到-20,999。错误信息是文本字符串,最多为2048字节。TRUE和FALSE表示是添加(TRUE)进错误堆(ERROR STACK)还是覆盖(overwrite)错误堆(FALSE)。缺省情况下是FALSE。
  
  如下代码所示:
  IF product_not_found THEN
  RAISE_APPLICATION_ERROR(-20123,'Invald product code' TRUE);
  END IF;
  
   4、异常的处理
  
  PL/SQL程序块的 异常部分包含了程序处理错误的代码,当 异常被抛出时,一个 异常陷阱就自动发生,程序控制离开执行部分转入 异常部分,一旦程序进入 异常部分就不能再回到同一块的执行部分。下面是 异常部分的一般语法:
  EXCEPTION
  WHEN exception_name THEN
  Code for handing exception_name
  [WHEN another_exception THEN
  Code for handing another_exception]
  [WHEN others THEN
  code for handing any other exception.]
  
  用户必须在独立的WHEN子串中为每个 异常设计 异常处理代码,WHEN OTHERS子串必须放置在最后面作为缺省处理器处理没有显式处理的 异常。当 异常发生时,控制转到 异常部分, ORACLE查找当前 异常相应的WHEN..THEN语句,捕捉 异常,THEN之后的代码被执行,如果错误陷阱代码只是退出相应的嵌套块,那么程序将继续执行内部块END后面的语句。如果没有找到相应的 异常陷阱,那么将执行WHEN OTHERS。在 异常部分WHEN 子串没有数量限制。
  EXCEPTION
  WHEN inventory_too_low THEN
  order_rec.staus:='backordered';
  replenish_inventory(inventory_nbr=>
  inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
  WHEN discontinued_item THEN
  --code for discontinued_item processing
  WHEN zero_divide THEN
  --code for zero_divide
  WHEN OTHERS THEN
  --code for any other exception
  END;
  
  当 异常抛出后,控制无条件转到 异常部分,这就意味着控制不能回到 异常发生的位置,当 异常被处理和解决后,控制返回到上一层执行部分的下一条语句。
  BEGIN
  DECLARE
  bad_credit exception;
  BEGIN
  RAISE bad_credit;
  --发生 异常,控制转向;
  EXCEPTION
  WHEN bad_credit THEN
  dbms_output.put_line('bad_credit');
  END;
  --bad_credit 异常处理后,控制转到这里
  EXCEPTION
  WHEN OTHERS THEN
  
  --控制不会从bad_credit 异常转到这里
  
  --因为bad_credit已被处理
  
  END;
  
  当 异常发生时,在块的内部没有该 异常处理器时,控制将转到或传播到上一层块的 异常处理部分。
  
  BEGIN
  DECLARE ---内部块开始
  
  bad_credit exception;
  BEGIN
  RAISE bad_credit;
  
  --发生 异常,控制转向;
  EXCEPTION
  WHEN ZERO_DIVIDE THEN --不能处理bad_credite 异常
  dbms_output.put_line('divide by zero error');
  
  END --结束内部块
  
  --控制不能到达这里,因为 异常没有解决;
  
  -- 异常部分
  
  EXCEPTION
  WHEN OTHERS THEN
  --由于bad_credit没有解决,控制将转到这里
  END;
  
   5、异常的传播
  
  没有处理的 异常将沿检测 异常调用程序传播到外面,当 异常被处理并解决或到达程序最外层传播停止。在声明部分抛出的 异常将控制转到上一层的 异常部分。
  
  BEGIN
  executable statements
  BEGIN
  today DATE:='SYADATE'; --ERRROR
  
  BEGIN --内部块开始
  dbms_output.put_line('this line will not execute');
  EXCEPTION
  WHEN OTHERS THEN
  
  -- 异常不会在这里处理
  
  END;--内部块结束
  EXCEPTION
  WHEN OTHERS THEN
  
  处理 异常
  
  END
--------------------------------------------------------------------------
1.简介
  异常处理块中包含了与 异常相关的错误发生以及当错误发生时要进行执行和处理的代码。 异常部分的语法一般如下:
BEGIN
  EXCEPTION
  
WHEN  Excep_Name1  THEN
    Statements1;
  
WHEN  Excep_Name2  THEN
    Statements2;
  
WHEN  OTHERS  THEN
    Statements3;
END ;

2.预定义异常
简单列一下常用的吧:

异常

异常标题

异常

ACCESS_INTO_NULL

ORA-06530

-6530

CASE_NOT_FOUND

ORA-06592

 -6592

COLLECTION_IS_NULL

ORA-06531

-6531

CURSOR_ALREADY_OPEN

ORA-06511

-6511

DUP_VAL_ON_INDEX

ORA-00001

 -1

INVALID_CURSOR

ORA-01001

-1001

INVALID_NUMBER

ORA-01722

-1722

LOGIN_DENIED

ORA-01017

-1017

NO_DATA_FOUND

ORA-01403

-1403

NOT_LOGGED_ON

ORA-01012

 -1012

PROGRAM_ERROR

ORA-06501 

 -6501

ROWTYPE_MISMATCH

ORA-06504

 -6504

SELF_IS_NULL

ORA-30625

-30625

STORAGE_ERROR

ORA-06500

-6500

SUBSCRIPT_BEYOND_COUNT

ORA-06533

-6533

SUBSCRIPT_OUTSIDE_LIMIT

ORA-06532 

-6532

SYS_INVALID_ROWID

ORA-01410

-1410

TIMEOUT_ON_RESOURCE

ORA-00051

-51

TOO_MANY_ROWS

ORA-01422

-1422

VALUE_ERROR

ORA-06502

-6502

ZERO_DIVIDE

ORA-01476

-1476


以上 异常说明:

异常

说明

ACCESS_INTO_NULL

Your program attempts to assign values to   the attributes of an  uninitialized (atomically null) object.

CASE_NOT_FOUND

one of the choices in the WHEN clauses of a  ASE  tatement is selected, and there is no  ELSE clause.

COLLECTION_IS_NULL

Your program attempts to apply collection methods other than EXISTS to an uninitialized (atomically null) nested table or varray, or the program attempts to assign values to the elements of an uninitialized nested table or varray.

CURSOR_ALREADY_OPEN

Your program attempts to open an alrea*** open cursor. A cursor must be closed before it can be reopened. A cursor FOR loop automatically opens the cursor to which it refers. So, your program cannot open that cursor inside the loop.

DUP_VAL_ON_INDEX

Your program attempts to store duplicate values in a database column that is constrained by a unique index.

INVALID_CURSOR

Your program attempts an illegal cursor operation such as closing an unopened cursor.

INVALID_NUMBER

In a SQL statement, the conversion of a character st***  into a number fails because the st***  does not represent a valid number. (In procedural statements, VALUE_ERROR is raised.) This exception is also raised when the LIMIT-clause expression in a bulk FETCH statement does not evaluate to a positive number.

LOGIN_DENIED

Your program attempts to log on to Oracle with an invalid username and/or password.

NO_DATA_FOUND

A SELECT INTO statement returns no rows, or your program references a deleted element in a nested table or an uninitialized element in an index-by table. SQL aggregate functions such as AVG and SUM always return a value or a null. So, a SELECT INTO statement that calls an aggregate function never raises NO_DATA_FOUND. The FETCH statement is expected to return no rows eventually, so when that happens, no exception is raised.

NOT_LOGGED_ON

Your program issues a database call without being connected to Oracle.

PROGRAM_ERROR

PL/SQL has an internal problem.

ROWTYPE_MISMATCH

The host cursor variable and PL/SQL cursor variable involved in an assignment have incompatible return types. For example, when an open host cursor variable is passed to a stored subprogram, the return types of the actual and formal parameters must be compatible.

SELF_IS_NULL

Your program attempts to call a MEMBER method on a null instance. That is, the built-in parameter SELF (which is always the first parameter passed to a MEMBER method) is null.

STORAGE_ERROR

PL/SQL runs out of memory or memory has been corrupted.

SUBSCRIPT_BEYOND_COUNT

Your program references a nested table or varray element using an index number larger than the number of elements in the collection.

SUBSCRIPT_OUTSIDE_LIMIT

Your program references a nested table or varray element using an index number (-1 for example) that is outside the legal range.

SYS_INVALID_ROWID

The conversion of a character st***  into a universal rowid fails because the character st***  does not represent a valid rowid.

TIMEOUT_ON_RESOURCE

A time-out occurs while Oracle is waiting for a resource.

TOO_MANY_ROWS

A SELECT INTO statement returns more than one row.

VALUE_ERROR

An arithmetic, conversion, truncation, or size-constraint error occurs. For example, when your program selects a column value into a character variable, if the value is longer than the declared length of the variable, PL/SQL aborts the assignment and raises VALUE_ERROR. In procedural statements, VALUE_ERROR is raised if the conversion of a character st***  into a number fails. (In SQL statements, INVALID_NUMBER is raised.)

ZERO_DIVIDE

Your program attempts to divide a number by zero.


3.自定义异常
  异常不一定必须是 Oracle返回的系统错误,用户可以在自己的应用程序中创建可触发及可处理的自定义 异常,调用 异常处理需要使用RAISE语句。
  异常情态的传播指的是当在程序块的声明、执行、 异常部分分别出现 异常情态时,或在本块中没有相应的 异常处理器时会将这个 异常情态传播到哪里,会去激发那个块中的处理器。传播规则是这样的:当一个 异常情态是在块的执行部分引发的(最常见的),PL/SQL使用下面的规则确定激活哪个 异常处理器。
  ① 若当前块对该 异常情态设置了处理器,则执行它并成功完成该块的执行,然后控制转给包含块。
  ② 若当前块没有该处理器,则通过在包含块中引发它来传播 异常情态。然后对包含块执行PL/SQL的 异常操作。另外,无论是在声明部分引发了一个 异常情态,还是在 异常处理部分引发,则该 异常情态将立即传播给包含块。在包含块引用上述规则进行 异常情态的处理,即使在当前块设置了OTHERS处理器也不会被执行。

你可能感兴趣的:(Oracle异常)