欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

oracle学习笔记(十六) PL/SQL 异常和goto语句

程序员文章站 2022-04-13 22:29:10
PL/SQL 异常和goto语句 异常 预定义异常 oracle常见预定义异常: |错误号 |异常错误信息名称 |说明 | | | | | |ORA 0001 |DUP_VAL_ON_INDEX | 试图破坏一个唯一性限制 | |ORA 0051 |TIMEOUT_ON_RESOURCE(少用) | ......

pl/sql 异常和goto语句

异常

预定义异常

oracle常见预定义异常:

错误号 异常错误信息名称 说明
ora-0001 dup_val_on_index 试图破坏一个唯一性限制
ora-0051 timeout_on_resource(少用) 在等待资源时发生超时
ora-0061 transaction_backed_out(少用) 由于发生死锁事务被撤消
ora-1001 invalid_cursor 试图使用一个未打开的游标
ora-1012 not_logged_on(少用) 没有连接到oracle
ora-1017 login_denied(少用) 无效的用户名/口令
ora-1403 no_data_found select into没有找到数据
ora-1422 too_many_rows select into 返回多行
ora-1476 zero_divide 试图被零除
ora-1722 invalid_number 转换一个数字失败
others(总是写在最后) 其它的异常(总是放在异常处理块的最后)

oracle内置有两个与异常有关的函数

  • sqlcode 返回oracle的错误代码
  • sqlerrm 返回oracle的错误消息
--使用预定义异常
declare
  v_empno employee.empno%type;
  rec_emp employee%rowtype;
begin
  v_empno := &请输入员工编号;
  select * into rec_emp from employee;-- where empno=v_empno;
  dbms_output.put_line('编号:'||rec_emp.empno||', 姓名:'||rec_emp.ename);
  
  --异常处理
  exception
    when no_data_found then --数据未找到
        dbms_output.put_line('数据未找到,原因:'||sqlcode||','||sqlerrm);
    when too_many_rows then
        dbms_output.put_line('数据过多,不能给变量赋值,原因:'||sqlcode||','||sqlerrm);
    when others then
      dbms_output.put_line('未知异常,原因:'||sqlcode||','||sqlerrm);
end;
/

自定义异常

  1. 声明异常: 变量名 exception;
  2. 抛出异常: raise 变量名;
  3. 处理异常:exception
--问题:如果某员工没有奖金时抛出“无奖金异常”
declare
  v_empno employee.empno%type := &请输入编号;
  rec_emp employee%rowtype;
  ex_no_comm  exception; --定义无奖金异常
begin
  select * into rec_emp from employee where empno=v_empno;
  if (rec_emp.comm is null or rec_emp.comm=0) then
    raise ex_no_comm;--2. 抛出异常
  end if;
  --3. 异常处理
  exception
    when ex_no_comm then
      dbms_output.put_line('无奖金异常');
end;
/

异常交给java处理(了解)

使用sql中的函数raise_application_error(error_number, error_message)即可把异常交给java处理。
java中通过try捕获到sqlexception,之后通过sqlexception的getcode和getmessage方法来获得

goto语句

--若xxx员工的工资小于奖金的 3倍,则为该员工的工资增加30%。
declare
  v_empno employee.empno%type;
  v_sal employee.sal%type;
  v_comm employee.comm%type;
begin
  v_empno := &请输入员工编号;
  select sal,comm into v_sal,v_comm from employee where empno=v_empno;
  if v_sal<nvl(v_comm,0)*3 then
    goto updating;
  end if;
  
  --定义标号
  <<updating>>
     update employee set sal=sal+sal*0.3 where empno=v_empno;
     commit;
  <<quit>>
    null; --空语句,什么都不做
end;
/