Oracle存储过程---异常
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 除数为 0
subscript_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在等待资源时超
还没有评论,来说两句吧...