Oracle学习笔记(三十)——pl/sql的进阶之例外处理

例外处理
1、例外的分类
     1)预定义例外:用于处理常见的oracle错误。
     2)非预定义例外:用于处理与定义例外不能处理的例外。
     3)自定义例外:用于处理与oracle错误无关的其他情况。

2、例外传递
     1)编写一个过程,可接收雇员的编号,并显示该雇员的姓名。
  • 如果输入的雇员编号不存在,如何处理?
  • SQL> --例外处理案例
    SQL> declare
      2  v_ename emp.ename%type;
      3  begin
      4    select ename into v_ename from emp where empno=&no;
      5    dbms_output.put_line('名字:'||v_ename);
      6    exception when no_data_found then
      7      dbms_output.put_line('编号不存在,请重新输入!');
      8  end;
      9  /
    编号不存在,请重新输入!
    PL/SQL procedure successfully completed

3、预定义例外
     1)预定义例外
  • 由pl/sql所提供的系统例外。
  • 当pl/sql应用程序违反了oracle规定的限制时,则会隐含触发一个内部例外。
  • pl/sql为开发人员提供了20多个预定义例外。

     2)预定义例外case_not_found
  • when子句中没有包含必须的条件分支,就会触发case_not_found的例外。
  • SQL> --case_not_found
    SQL> create or replace procedure sp_pro11(spno number) is
      2  v_sal emp.sal%type;
      3  begin
      4    select sal into v_sal from emp where empno=spno;
      5    case
      6      when v_sal<1000 then
      7        update emp set sal=sal+100 where empno=spno;
      8      when v_sal<2000 then
      9        update emp set sal=sal+200 where empno=spno;
     10      end case;
     11    exception
     12      when case_not_found then
     13        dbms_output.put_line('case语句没有与'||v_sal||'相匹配的条件');
     14  end;
     15  /
    Procedure created

     3)预定义例外cursor_already_open
  • 当重新打开已经打开的游标时,会隐含触发例外cursor_already_open。
  • SQL> --cursor_already_open
    SQL> declare
      2  cursor emp_cursor is select ename,sal from emp;
      3  begin
      4    open emp_cursor;
      5    for emp_reacord1 in emp_cursor loop
      6      dbms_output.put_line(emp_record1.ename);
      7    end loop;
      8    exception
      9      when cursor_already_open then
     10        dbms_output.put_line('游标已经打开');
     11  end;
     12  /

      4)预定义例外dup_val_on_index
  • 在唯一索引所对应的列上插入重复的值时,会隐含触发例外dup_val_on_index。
  • SQL> --dup_val_on_index
    SQL> begin
      2    insert into dept values(10,'公关部','北京');
      3    exception
      4      when dup_val_on_index then
      5        dbms_output.put_line('在deptno列上不能出现重复值');
      6  end;
      7  /
    在deptno列上不能出现重复值
    PL/SQL procedure successfully completed

      5)预定义例外invalid_cursor
  • 当试图在不合法的有表上执行操作时,会触发该例外。
  • 例如:试图从没有打开的游标提取数据,或是关闭没有打开的游标,则会触发该例外。
  • SQL> --invalid_cursor
    SQL> declare
      2  cursor emp_cursor is select ename,sal from emp;
      3  emp_record emp_cursor%rowtype;
      4  begin
      5    --open emp_cursor;--打开游标
      6    fetch emp_cursor into emp_record;
      7    dbms_output.put_line(emp_record.ename);
      8    close emp_cursor;
      9    exception
     10      when invalid_cursor then
     11        dbms_output.put_line('请检查游标是否打开');
     12  end;
     13  /
    请检查游标是否打开
    PL/SQL procedure successfully completed

      6)预定义例外invalid_number
  • 当输入的数据有误时,会触发该例外。
  • 比如:数字100写成了1oo就会触发该例外。
  • SQL> --invalid_number
    SQL> begin
      2    update emp set sal=sal+'1oo';
      3    exception
      4      when invalid_number then
      5        dbms_output.put_line('输入的数字不正确');
      6  end;
      7  /
    输入的数字不正确
    PL/SQL procedure successfully completed

      7)预定义例外no_data_found
  • 当执行select into没有返回航,就会触发该例外。
  • --no_data_found
    declare
    v_sal emp.sal%type;
    begin
      select sal into v_sal from emp where ename= '&name';
      exception
        when no_data_found then
          dbms_output.put_line( '不存在该员工' );
    end;

      8)预定义例外too_many_rows
  • 执行select into语句时,如果返回超过了一行,则会触发该例外。
  • SQL> --too_many_rows
    SQL> declare
      2  v_ename emp.ename%type;
      3  begin
      4    select ename into v_ename from emp;
      5    exception when too_many_rows then
      6      dbms_output.put_line('返回了多行');
      7  end;
      8  /
    返回了多行
    PL/SQL procedure successfully completed

      9)预定义例外zero_divide
  • 当执行除法运算时,如果分母为0,则会触发该例外。

     10)预定义例外value_error
  • 在执行赋值操作时,如果变量的长度不足以容纳实际数据,则会触发该例外value_error。
  • SQL> --value_error
    SQL> declare
      2  v_ename varchar2(5);
      3  begin
      4    select ename into v_ename from emp where empno=&no;
      5    dbms_output.put_line(v_ename);
      6    exception
      7      when value_error then
      8        dbms_output.put_line('变量长度不够');
      9  end;
     10  /
    变量长度不够
    PL/SQL procedure successfully completed

     11)其它预定义例外
  • login_denide:用户非法登录。
  • not_logged_on:用于未登录就执行dml操作。
  • storage_error:超出了内存空间或是内存被损坏。
  • timeout_on_resource:oracle在等待资源时,出现超时。

4、非预定义例外
     1)非预定义例外:用于处理与与定义例外无关的oracle错误。
  • 预定义例外只可以处理21个oracle错误,而当使用pl/sql开发应用程序时,可能会遇到其它的一些oracle错误。比如在pl/sql块中执行dml语句时,违反了约束规定等。在这样的情况下,也可以处理oracle的各种例外。

5、处理自定义例外
  • 自定义例外与oracle错误没有任何关联,是由开发人员为特定情况所定义的例外。
  • 编写一个pl/sql块,接收一个雇员的编号,并给该雇员工资增加1000元,如果该雇员不存在,请提示。
    •     SQL> --自定义例外
          SQL> create or replace procedure ex_test(spNo number) is
            2  --定义一个例外
            3  myex exception;
            4  begin
            5    update emp set sal=sal+100 where empno=spNo;
            6    --sql%notfound表示没有upadate成功
            7    --raise myex;触发myex
            8    if sql%notfound then
            9      raise myex;
           10    end if;
           11    exception
           12      when myex then
           13        dbms_output.put_line('没有更新任何例外');
           14  end;
           15  /
          Procedure created
      
          SQL> exec ex_test(56);
          没有更新任何例外
          PL/SQL procedure successfully completed
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值