Oracle存储过程---异常

来源:互联网 发布:精灵乐章 知乎 编辑:程序博客网 时间:2024/05/21 22:32

Oracle异常分预定义异常和自定义异常(个人觉得)。

预定义异常里面包括匿名异常和非匿名异常。

(匿名异常:没有名称,像ORA-00371

非匿名异常:有名称,像no_data_found)。

自定义异常:需要声明,与业务相关。

异常的抛出用raise。在exception捕获后,可以向上继续raise抛出。

exception代码块捕获后,如果想把异常反应给应用程序,使用

raise_application_error(-20000'自定义异常:空字符串!'false);

raise_application_error(-20000'自定义异常:空字符串!');

第一个参数是错误号,从 -20000到 -20999.

第二个参数是错误信息。

第三个参数,boolean类型,默认false,可以不写这个参数。

true(添加进错误堆栈)false(覆盖错误堆栈)

plsql中执行的效果就是弹出错误提示框。

create or replace procedure pro_ten(p_one in varchar2, p_two out varchar2) is  exception_customized_one exception; --自定义异常1  exception_customized_two exception; --自定义异常2  exception_customized_three exception; --自定义异常3,与oracle内部匿名异常的绑定  pragma exception_init(exception_customized_three,-371);--  例如:ORA-00371: 共享池内存不足 begin  dbms_output.put_line('传参:' || 'p_one:' || p_one || 'p_one长度:' ||                       length(p_one) || 'trim后长度:' || length(trim(p_one)));  if (p_one is null or trim(p_one) is null) then    -- 注意这里不能写成trim(p_one)='',根据实验结果就是这样的    raise exception_customized_one;  elsif (trim(p_one)='0' or trim(p_one)='0.0') then       raise exception_customized_two;  elsif (trim(p_one)='1') then       raise exception_customized_three;  else    begin      p_two := p_one || '  has changed';      dbms_output.put_line('返回结果:' || 'p_two:' || p_two);    end;  end if;exception  when exception_customized_one then    begin      dbms_output.put_line('exception -20000 occured, 自定义异常:空字符串!');      raise_application_error(-20000, '自定义异常:空字符串!', false);    end;  when exception_customized_two then      dbms_output.put_line('exception -20001 occured, 自定义异常:数字0出现!');      raise;--这里把异常向上继续抛出,交给调用者处理                  /*与内部异常绑定的自定义异常就不用捕获了,因为内部有异常Oracle检测并自动抛出的。      我们绑定的目的就是把不在人家定义的范围的情况加进去,让oracle认识我们定义的情况。      这样异常就直接到others代码块了*/  /*when exception_customized_three then      dbms_output.put_line(SQLERRM);      raise exception_customized_three;*/  when others then    dbms_output.put_line('others exception!');    dbms_output.put_line(SQLERRM);--错误信息    raise;--这里把异常向上继续抛出,交给调用者处理end pro_ten;


测试上面3种异常:


Oracle预定义的21个非匿名异常列表:access_into_null 未定义对象case_not_found    case中若未包含相应的when,并且没有设置collection_is_null  集合元素未初始化curser_already_open   游标已经打开dup_val_on_index   唯一索引对应的列上有重复的值invalid_cursor   在不合法的游标上进行操作invalid_number   内嵌的 sql 语句不能将字符转换为数字no_data_found    使用 select into 未返回行,或应用索引表未初始化的too_many_rows    执行 select into 时,结果集超过一行zero_divide      除数为 0subscript_beyond_count   元素下标超过嵌套表或varray的最大值subscript_outside_limit  使用嵌套表或 varray 时,将下标指定为负数value_error     赋值时,变量长度不足以容纳实际数据login_denied     pl/sql 应用程序连接到 oracle 数据库时,提供了不正确的用户名或密码 not_logged_on     pl/sql 应用程序在没有连接 oralce 数据库的情况下访问数据 program_error     pl/sql 内部问题,可能需要重装数据字典& pl./sql系统包 rowtype_mismatch   主游标变量与 pl/sql 游标变量的返回类型不兼容self_is_null     使用对象类型时,在 null 对象上调用对象方法storage_error    运行 pl/sql 时,超出内存空间sys_invalid_id   无效的 rowid 字符串timeout_on_resource   oracle在等待资源时超



 

 

 

原创粉丝点击