Oracle Database :玩转Oracle学习笔记之(10):异常

Ⅰ、例外的分类:
Oracle将例外分为预定义例外,非预定义例外和自定义例外三种;

①、预定义例外处理常见的oracle错误;
②、非预定义例外处理预定义例外不能处理的例外;
③、自定义例外处理与oracle无关的其他情况;

--例外案例;
declare
    v_ename emp.ename%type;
begin
    select ename into v_ename from emp where empno=&no;
    dbms_output.put_line('Name : '||v_ename);
    exception
    when no_data_found then
        dbms_output.put_line('编号不存在');
end;



Ⅱ、处理预定义例外:处理预定义例外是由pl/sql所提供的系统例外。当pl/sql应用程序违反了oracle规定的限制时候,则会隐含触发一个内部例外。pl/sql为开发人员提供了二十多种预定义例外;

㈠、预定义例外:case_not_found;
在开发pl/sql的时候,编写case语句时候,如果在when子句中没有包含必须的分支,就会触发此例外;

--case_not_found;

create or replace procedure mypro(spNo number) is
    v_sal emp.sal%type;
begin
    select sal into v_sal from emp where empno=spNo;
    case
    when v_sal<1000 then
        update emp set sal=sal+100 where empno=spNo;
    when v_sal<2000 then
        update emp set sal=sal+200 where empno=spNo;
    end case;
    
    exception
    when case_not_found then
        dbms_output.put_line('case语句中没有与'||v_sal||'想匹配的条件');
end mypro;


SQL> exec mypro(7788);
case语句中没有与3000想匹配的条件

PL/SQL procedure successfully completed.



㈡、预定义例外:cursor_already_open:
当重新打开已经打开的游标时候,就会隐含的触发例外;

㈢、dup_val_on_index:在唯一索引对应的列上插入重复的值时候,就会触发此例外;

㈣、invalid_cursor:当试图在不合法的游标上执行操作时候,就会触发该例外;
例如:试图从没有打开的游标中读取数据或关闭没有打开的游标;
--invalid_cursor

declare
    cursor emp_cursor is select ename , sal from emp;
    emp_record emp_cursor%rowtype;
begin
    --open emp_cursor;--打开游标;
    fetch emp_cursor into emp_record;
    dbms_output.put_line(emp_record.ename);
    close emp_cursor;
    exception
    when invalid_cursor then
        dbms_output.put_line('检查游标是否被打开!');
end;


㈤、invalid_number:当输入数据有误时候,会触发该例外;

begin
    update emp set sal=sal+'lpp';
    exception
    when invalid_number then
        dbms_output.put_line('输入数字不正确!');
end;




㈥、no_data_found:
declare
    v_sal emp.sal%type;
begin
    select sal into v_sal from emp where ename='&me';
    exception
    when no_data_found then
        dbms_output.put_line('不存在该员工');
end;



㈦、too_many_rows:在执行select语句时候,如果返回超过了一行,就会触发该例外:

declare
    v_ename emp.ename%type;
begin
    select ename into v_ename from emp;
    exception
    when too_many_rows then
        dbms_output.put_line('返回行多了');
end;


㈧、zero_divide:


SQL> declare
  2  v_divided number;
  3  begin
  4  select 4/&num into v_divided from dual;
  5  exception
  6  when zero_divide then
  7  dbms_output.put_line('除数不能为零');
  8  end;
  9  /
Enter value for num: 0
old   4: select 4/&num into v_divided from dual;
new   4: select 4/0 into v_divided from dual;
除数不能为零

PL/SQL procedure successfully completed.



㈨、value_error:
当执行赋值操作的时候,如果变量的长度不足以容纳实际数据,则会触发该例外:value_error;

declare
    v_ename varchar2(2);
begin
    select ename into v_ename from emp where empno=7788;
    dbms_output.put_line(v_ename);
    exception
    when value_error then
        dbms_output.put_line('变量尺寸不足');
end;



㈩、其他预定义例外:
①、login_denide:当用户非法登录时候,会触发该例外;
②、not_logged_on:如果用户没有登录就执行dml操作,就会触发该例外
③、storage_error:如果超出了内存空间或是内存被损坏,就会触发该事件;
④、timeout_on_resource:如果oralce在等待资源时候,出现了超时就会触发该例外;

Ⅲ、非预定义例外:用于处理与预定义例外无关的oracle错误,使用预定义例外只能处理oracle已经定义好了的oracle错误,而当使用pl/sql开发时候,可能会遇到其他一些错误,比如在pl/sql块中执行dml语句时候,违反了约束规定等等。



Ⅳ、处理自定义例外:
预定义例外和非预定义例外都是与oracle错误相关的,并且出现的oracle错误会隐含的触发相应的例外;而自定义例外和oracle错误没有任何关联,它是由开发人员在特定情况下定义的例外;

比如:
--自定义例外;
create or replace prcedure mypro(spNo number) is
begin
    --更新用户;
    update emp set sal=sal+1000 where empno=spNo;
end mypro;



当执行的时候,如果输入34,不会出现异常,因为在更新的时候,oracle直接认为用户不存在就是了;

但是

--预定义例外;
create or replace prcedure mypro(spNo number) is
begin
    --查询用户;
    select  sal from emp where empno=spNo;
end mypro;



当执行的时候,如果输入34,会出现异常,因为在查询的时候,oracle会认为他是一个异常;

这时候,如果我们希望第一种更新的情况作出提示,我们就需要自定义例外:


SQL> --自定义例外;
SQL> create or replace procedure mypro(spNo number) is
  2  --定义一个例外;
  3  myex exception;
  4  begin
  5  --更新用户sal;
  6  update emp set sal=sal+1000 where empno=spNo;
  7
  8  --sql%notfound表示sql没有更新成功;
  9  if sql%notfound then
 10
 11  --raise myex: 触发myex;
 12  raise myex;
 13
 14  end if;
 15
 16  exception
 17  when myex then
 18  dbms_output.put_line('没有更新任何数据');
 19  end;
 20  /

Procedure created.

SQL> call mypro(23);
没有更新任何数据



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值