oracle数据库----笔记1---PL/SQL基础4---异常处理

PL/SQL中的例外(异常)处理:

例外处理是用来处理程序在正常执行过程中所出现未预料
的事件

由于设计问题,代码错误,硬件故障等许多其它原因都
会引起程序运行中的错误

虽然不能预测所有可能的错误,但
可以在程序中规划处理某些类型的错误

在PL/SQL程序块中一旦发生异常,就会终止该程序块执行

PL/SQL程序块中引入对异常进行处理,使程序在出错时可继 
续运行

例外有两种:内部例外和用户定义例外

内部例外:

是运行系统预先定义的例外,如除数为零,内存不足,执行查询
语句未查询到数据等等

ZERO_DIVIDE                              除以0引起的
STORAGE_ERROR                            用完了内存或者内存存储破坏引起的
NO_DATA_FOUND                            执行select into 语句时没有行返回或引用PL/SQL表中未初始化的行
TOO_MANY_ROWS                            PL/SQL中未使用游标,执行select into语句返回了多行数据引起
INVALID_CURSOR                           执行一个非法的游标操作引起的,比如,关闭未打开的游标
DUP_VAI_ON_INDEX                         在具有唯一索引约束的数据库系列上存储一个重复值而引起
CURSOR_ALREADY_OPEN                      试图打开一个已经打开的图标

用户自定义的例外:

该例外必须要在说明部分定义, 给予命名
并用RAISE语句在
执行部分显式地引发该例外

若程序中给出例外处理,当一个
错误发生时,一个例外被引起,即正常的操作被停止,将流程控制
转移到程序的例外处理部分 

对例外的处理过程是放在程序块的执行部分后面, 由关键字
EXCEPTION开始

在PL/SQL程序块中例外处理部分可处理
一个或多个例外, 例外处理放在例外处理部分的WHEN子句
之后。



例外处理部分程序格式
 EXCEPTION  
 
            WHEN    例外名表1  THEN
    
                      语句序列1

             WHEN    例外名表2  THEN
 
                       语句序列2
 
             ........
             [WHEN  OTHERS  THEN
    
                       语句序列n ]



 在每个WHEN之后,列出例外名表,例外名多于一个时,由OR关键字将多个例外名分开,

OTHERS例外处理是可选的,
在一个PL/SQL块或子程序的例处处理部分仅出现一次

对指定这些例外名的处理,可按任意次序排列,OTHERS例外处理必须排在最后

给出OTHERS例外处理,使程序保证了没有例外是未被处理

 SQL>  set  serveroutput  on
  
declare
  
   x   number ;
begin
    
    x:=1/0;
  
    dbms_output.put_line(‘works’);
  
exception 
  
    when  value_error  then
 
         dbms_output.put_line(‘value  error’);
 
    when  others  then
  
         dbms_output.put_line(‘other  error’);
 
end;  

用户定义的例外处理:

PL\SQL允许在程序中用户自己定义例外,称为用户定义例外

用户定义的例外必须要在程序块的说明部分进行说明   

并在执 
 行部分用RAISE语句显示地引发例外

例外说明形式:
   
例外名         EXCEPTION;

例外说明和变量说明类似 , 但要注意其区别:

1.例外是一个出错条件, 不是一种对象, 与变量不同,例外名不能
 出现在赋值语句和SQL语句中

2.在同一个块中一个例外名不能被说明两次, 但同一个例外名
  可在不同块中被说明

3.例外说明在说明它的块中是局部的, 而对于它的所有子块来
 说它是全局的。

4.在一子块中可引用局部或全局例外,而在包装
 块中不能引用在子块中说明的例外

5.如果在子块中重新说明一个全局例外, 该局部说明占优势, 以致子块不能引用全局例外,  

   除非用块标号说明, 形式为:
 块标号 ·  例外名


DECLARE
  
     salary_code   varchar2(1) ;

     invaliad_salary_code  EXCEPTION;
  
BEGIN
    
       salary_code:=’X’;
 
       if  salary_code  NOT  IN (‘A’,’B’,’C’) THEN
  
            RAISE  invaliad_salary_code; 

       end if;
       
      dbms_output.put_line(‘ok’);
 
EXCEPTION
  
       when  invaliad_salary_code  then

       dbms_output.put_line(‘invaliad  salary  code’);
END;


对自定义的例外名在执行部分被语句RAISE触发。当触发了
  例外后,执行就被传递给程序块的例外处理部分。

一旦自定义例外被触发, 为它所创建的异常处理器就被执行

查询EMP表中所有雇员工资,若发现大于¥10000者,说明出错并退出

DECLARE 
  
   v_sal_err  emp.sal%TYPE:=10000;
  
   CURSOR  C1  IS
    
   SELECT   sal  
    FROM   EMP;

   v_sal  emp.sal%TYPE;
 
   sal_error  EXCEPTION;
 
BEGIN
   
   OPEN  C1;

   FETCH  C1  INTO  v_sal ;
   
LOOP
  
      EXIT  WHEN  C1%NOTFOUND;
  
      IF  v_sal>10000
      
         RAISE   sal_error ;
   
      ELSE
  
         FETCH   C1  INTO   v_sal ;

      END  IF ;
  
   END  LOOP;
   CLOSE   C1;
 
EXCEPTION
    
   WHEN  NO_DATA_FOUND   THEN
 
      INSERT   INTO   TMP(message)
      VALUSE(‘No found any  empoloyee’);
 
      CLOSE  C1;
   
   WHEN  sal_error    THEN              / *   对用户定义的例外处理   */
        
      INSERT   INTO   TMP(message)

      VALUSE(‘found  error : sal>10000’);
      CLOSE  C1;
   
   WHEN   OTHERS   THEN
  
     INSERT  INTO  TEMP(message)
 
     VALUES (‘found other  error’:);
     CLOSE  C1;  
   
END ; 

Raise_application_error过程

可以使用oracle提供的标准包dbms_standard中所定义重新定义异常错误消息,
这为应用提供了一种与oracle交互的方法
的raise_application_error过程,  



使用的时候前面可以不加dbms_standard

过程raise_application_error的语法如下:
Raise_application_error(error_number,error_message,[keep_errors]);

其中

1.error_number:用户可自己定义,从-20000到-20999

2.error_message:是需要定义的相应提示信息,应小于2kb

3.keep_errors:可选项,如果为ture,则新错误添加到已经引发的错误列表,如为false,则新错误将替换当前错误列表。默认值为false


Declare 
  
V_eno emp.empno%type:=1344;
  
No_found exception; 

Begin

  update emp set sal=sal*1.1 
  where empno=v_eno;
	
  if sql%notfound then 

    raise no_found;
	
  end if;

Exception
 
  when no_found  then 

     raise_application_error(-20001,‘the number doesnot exist’);
  when others then
	
     dbms_output.put_line(‘other errors’);

End;

  

posted @ 2013-05-09 16:58  wust小吴  阅读(249)  评论(0编辑  收藏  举报