plsql(轻量版)_异常处理机制

一个优秀的程序都应该能够正确的处理各种出错异常,并尽可能的从错误中恢复,ORACLE提供异常来实现错误处理,

异常exception这个词还是这个,处理正常执行过程中未预料的事件,他分为预定义的错误,和自定义的错误,相当于

还可以自定义一个异常,由于PL/SQL块一旦产生异常,没有指出如何处理,程序就会自动的终止程序的运行,自动终止

程序的运行,就像JAVA里面也是一样的,他这里有三种异常的错误,第一种叫预定义的,预定义的大概有24种异常,然后这个时候

它会自动的给你抛出来如果你不使用exception给他捕获的话,那他就在这里停止了,如果你要捕获,你就使用exception给他

处理一下,这跟JAVA是一样的,非预定义的异常,就是其他标准的ORACLE错误,也是ORACLE指定的一个错误,但是他这个错误

和你自己定义的错误,来练习起来,然后自定义一个名,我们来说这两个怎么来写,比如我想查询一个人的工资,如果查工资低于

2千,工资太低本来没有啥问题,你只要这个工资低于多少钱,我就让你抛一个异常,就是你可以自定义一个异常,然后异常的格式,

在大的PL/SQL块里边,叫exception,在这里边写,如何处理这个异常,当时这个类型的时候,then如何处理,当你有多个异常,

when then,when other then

处理异常的方式,预定义的异常大概有24种,异常的情况,有错误号,其他错误的信息,要想捕获这个

异常,错误号它是自动会爆出来的,你把这个内容放到这,比如no_data_found,没有找到数据,你想更新里面的

一个人的工资,结果没有找到一条数据,他就会抛1403的错误,when no_data_found,then 打印一条说,没有找到数据

他里面有这个类型的,叫to_many_rows,我就查询一下,declare,定义一个叫v_salary,employees表里面,

salary,百分号,type,begin,select salary into v_salary,然后from employees,where,我先写一个100,

就是把100号的工资放到v_salary,dbms打印v_salary,这个程序,我们写上这个,exception,我们知道这里面可能

会出现什么异常,when..then..,这个发现没问题,100号的工资是24240

declare

	v_salary employees.salary%type;
	
begin

	select salary into v_salary from employees
	
	where employee_id = 100;
	
	dbms_output.put_line(v_salary);

end;

这儿这个程序,我们写上也行,只是我们现在不知道这里面会出现什么异常,我们这里改成一个大于,这显然不是一个人的

员工的查询结果了,正常我们要使用游标,这是多条记录,现在这里实际上是多条记录,实际返回的行数超出请求的行数

declare

	v_salary employees.salary%type;
	
begin

	select salary into v_salary
	
	from employees
	
	where employee_id > 100;
	
end;

too_many_rows这就是他错误的名字,错误的标号,那我在我相应的exception这里,when,叫to_many_rows,then,

输出的行数太多了,就这样写,这不就执行了

declare

	v_salary employees.salary%type;
	
begin

	select salary into v_salary
	
	from employees
	
	where employee_id > 100;
	
	dbms_output.put_line(v_salary);
	
exception

	when too_many_rows then dbms_output.put_line('输出的行数太多了!!!!!');
	
end;

输出的行数太多了,就这样写,相当于他抛出来这样一个对象一样,然后我们看这个对象对应的类型,

是这个类型的你给他输出,你也可以给他补一下,when others then,出现其他类型的异常的时候,这个就叫

预定义的异常,就是他出现异常的错误在这里面有标识了

declare

	v_salary employees.salary%type;
	
begin

	select salary into v_salary
	
	from employees
	
	where employee_id > 100;
	
	dbms_output.put_line(v_salary);
	
exception 

	when too_many_rows then dbms_output.put_line('输出的行太多了!!');
	
	when others then dbms_output.put_line('出现其他类型的异常了!');
	
end;

非预定义异常的处理,我们需要再PL/SQL块中声明一个异常,然后把你出现的错误代码,跟我这个异常的对象,

关联起来,使用这样一个语句,给我们操作一个

我使用SQL语句写一个,delete from employees,where employee_id等于100,说违反完整性约束条件

这个删除知道为什么不能删吗,外键有一个manager_id,但是manager_id是指向你自己的employee_id,

你删除这个主键的时候,外键manager_id有人指向他,所以他不让你删,这个叫2292,报这个错,这里面没有

2292,要是有的话你就when处理,他没有这个错误的24种,那你就得这样写,declare,那你就得自己定义这个

异常,叫delete_id,e_deleteid_exception,exception类型的,光这样写还不行,你得使用这个语句,给他关联起来,

pragma,是这样,然后把你这个名放到这,刚才出现这个错误号,2292,-2292,这就写完了,然后呢,begin,我们刚才想

删除的放到这,delete from,where,100号员工删除,他一删除的时候,他就抛这个错,然后exception,when,当你出现

这个异常的时候,违反完整性约束条件,故不可以删除此用户,end

declare

	v_deleteid_exception exception;
	
	pragma exception_init(e_deleteid_exception,-2292);
	
begin

	delete from employees where employee_id = 100;
	
exception

	when e_deleteid_exception then dbms_output.put_line('违反完整性约束条件,故不可以删除此用户!');
	
end;

他就不给你报这个错了,第一种区别呢,我们试图去查询一下salary的工资,结果我们发现长度过多了,

就因为这个错误,发现这个框里有,有的话,我们就可以用预定义的异常,结果这里有一些错误,发现他

报的号我这个表里找不到,既然这个号又给你爆出来了,说明ORACLE已经定义了这个错误,他有这个错,

那为就把这个错和我定义的异常关联起来,我就可以定义exception的类型一样,然后让这个变量和错误的

关联起来,当你一旦执行这个语句,发现发生这个错误编号的时候,就自动让你转成这个异常的变量,然后再给他

输出出来,这就叫非预定义异常,有预定义的异常,有非预定义的异常,还有个叫用户自定义的异常,用户自定义的,

用户定义的异常错误是显示用RAISE语句来触发的,当引发异常错误的时候,控制就会转向到EXCEPTION块异常错误的部分,

执行错误的代码,看看这个

我们这样,还是查询100号员工的工资,如果他的工资大于1万,我就抛一个异常说,工资太高了,

declare,还得声明一个异常的变量,e_too_high_sal,exception类型的,他得定义一个变量,整体要查的

员工的工资,然后begin,select salary into v_sal,from employees这个表,where employee_id等于100,

把100号员工的工资查出来,如果v_sal查出来大于1万的,then就处理,那怎么处理,就抛这个异常,如果你要是小于

1万的,我就不给你处理了,我就直接end if结束,没了,end,忘了exception了,你抛出来了你还没有处理呢,when,当你

发生这个异常的时候,then,dbms_output.put_line,打印,相当于你这个异常到底是干什么的,工资太高了,就这样一个,

declare

	e_too_high_sal_exception;
	
	v_sal employees.salary%type;
	
begin

	select salary into v_sal from employees where employee_id = 100;
	
	if v_sal > 10000 then
	
	raise e_too_high_sal;
	
	end if;
	
exception

	when e_too_high_sal then dbms_output.put_line('工资太高了!');
	
end;

相当于你这个异常是干什么的,工资太高了,这样一个,这个就叫用户自定义的异常,我们刚才定义的三个其实是

分开写的,你也可以给合起来,这个没问题,就是整个放在一起的话,我们有一个删除的,删除的在这,就是刚才这个,

delete的错误,delete里面我定义了这两个,非预定义的异常,然后执行一个delete,你们就看谁先执行,谁后执行了,

放在这的话detele先执行,delete如果没错的话,那就删了,有错的话,他就直接跑到这儿来了,你也可以再加上一个when,

others then,发生其他的异常了,然后给他end,执行的话只要你执行出现异常了,我就exception我就去找,后边的代码

就不再执行了,后边就会抛这个异常

这里就相当于子程序来执行,只要你执行到哪一块出现异常了,我就去exception里面去找,后边的代码就不再执行了,

所以就会抛这个异常,因为你这一块代码不会被执行,就这个意思,这是说的异常,异常后边还有一些练习,这三种异常的形式,

18. 异常的基本程序: 
通过 select ... into ... 查询某人的工资, 若没有查询到, 则输出 "未找到数据"

declare
  --定义一个变量
  v_sal employees.salary%type;
begin
  --使用 select ... into ... 为 v_sal 赋值
  select salary into v_sal from employees where employee_id = 1000;
  dbms_output.put_line('salary: ' || v_sal);
exception
  when No_data_found then 
       dbms_output.put_line('未找到数据');
end;

或

declare
  --定义一个变量
  v_sal employees.salary%type;
begin
  --使用 select ... into ... 为 v_sal 赋值
  select salary into v_sal from employees;
  dbms_output.put_line('salary: ' || v_sal);
exception
  when No_data_found then 
       dbms_output.put_line('未找到数据!');
  when Too_many_rows then 
       dbms_output.put_line('数据过多!');     
end;

如若没找到,就输出未找到数据,未找到数据,你先这样看一下,我们写这个题,你说这个叫预定义,

或者非预定义,这个也不好说,那你就先让他执行一下,他说让你查询某个人的工资,看这个人有没有,

我就declare,begin,select salary into,from employees,where,这样处理的话肯定没有问题,end他就能够找到,

他找到给他打印一下

declare

	v_sal employees.salary%type;
	
begin

	select salary into v_sal from employees where employee_id = 100;
	
	dbms_output.put_line(v_sal);
	
end;

这是他的工资,然后你要输出比如1001,这人不在,说未找到数据,这不就出现一个异常吗,ORA-1403,你在这找找

declare

	v_sal employees.salary%type;
	
begin

	select salary from employees where employee_id = 1001;
	
	dbms_output.put_line(v_sal);
	
end;

有的话就是预定义的,没有的话你得自己去定义一个,1403就是这个吧,有这个就好办了,就是预定义的,

就是定义好的

在这儿,exception,when,no_data_found,then,查无此人,那就这样子,这个就相当于叫预定义的

declare

	v_sal employees.salary%type;
	
begin

	select salary into v_sal from employees where employee_id = 100;
	
	dbms_output.put_line(v_sal);
	
exception

	when no_data_found then dbms_output.put_line('查无此人');
	
end;

这个相当于是预定义的,还有对应的异常的类型,没有的话就自己造一个

19. 更新指定员工工资,如工资小于300,则加100;对 NO_DATA_FOUND 异常, TOO_MANY_ROWS 进行处理.
declare
   v_sal employees.salary%type;
begin
   select salary into v_sal from employees where employee_id = 100;
   
   if(v_sal < 300) then update employees set salary = salary + 100 where employee_id = 100;
   else dbms_output.put_line('工资大于300');
   end if;
exception
   when no_data_found then dbms_output.put_line('未找到数据');
    when too_many_rows then dbms_output.put_line('输出的数据行太多');
end;

如果工资小于300,加100,对于没有找到数据的,还有输出行太多的,更新指定员工的工资,如果工资小于300,

指定员工的,工资小于300,也得先定义一个工资,然后把工资给他放在这里边,假设101这个人,放到这里面,然后,

我判断一下,这个v_sal他是否是小于300的,如果是小于300的,则加100,then的话加100,salary加100,then相当于

做一个更新操作,如果你这个人的工资小于300,我就update,employees,set,salary等于salary加上100,指定员工的,

这是对于确实小于100,如果你这个员工可能不在,不在的话就输出他,还有可能说你写的这个salary,employee_id,

when too_many_rows,then,输出的行太多了,就这样处理,101我们看这个,end if,说明就没有异常

declare

	v_sal employees.salary%type;
	
begin

	select salary into v_sal from employees where employee_id = 101;
	
	if v_sal<300 then update employees set salary=salary+100 where employee_id = 101;
	
	end if;
	
exception

	when no_data_found then dbms_output.put_line('查无此人');
	
	when too_many_rows then dbms_output.put_line('输出的行数太多了!');
	
end;

20. 处理非预定义的异常处理: "违反完整约束条件"

declare
  --1. 定义异常	
  temp_exception exception;

  --2. 将其定义好的异常情况,与标准的 ORACLE 错误联系起来,使用 EXCEPTION_INIT 语句
  PRAGMA EXCEPTION_INIT(temp_exception, -2292);
begin
  delete from employees where employee_id = 100;

exception
  --3. 处理异常
  when temp_exception then
       dbms_output.put_line('违反完整性约束!');
end;

删除这个人,包2292这个异常,关联起来,然后在when这里接收

21. 自定义异常: 更新指定员工工资,增加100;若该员工不存在则抛出用户自定义异常: no_result

declare
  --自定义异常                                   
  no_result exception;   
begin
  update employees set salary = salary + 100 where employee_id = 1001;

  --使用隐式游标, 抛出自定义异常
  if sql%notfound then
     raise no_result;
  end if;  

exception

  --处理程序抛出的异常
  when no_result then
     dbms_output.put_line('更新失败');
end;

它使用用户自定义的,正常这个员工不存在的话,直接使用no_data_found就可以了,还有想用户自定义的也行,

update employees set salary = salary + 100,当employee_id是他的时候,它使用的叫隐式游标,因为这个是异常数据,

判断是否在,就raise一个异常,这个对象是我自定义的,我们看一下就行,更新失败

declare

	no_result exception;
	
begin

	update employees set salary = salary + 100 where employee_id = 100;
	
	if sql%notfound then
	
		raise no_result;
		
	end if;
	
exception

	when no_result then
	
		dbms_output.put_line('更新失败');
		
end;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值