pl/sql编程----例外

例外的分类:
oracle将例外分为预定义例外,非预定义例外和自定义例外
预定义例外:用于处理常见的oracle错误;预定义例外是由pl/sql所提供的系统例外,当pl/sql应用程序违反了oracle规定的限制时,则会隐含的触发一个内部例外,pl/sql为开发人员提供了二十多个预定义例外;
非预定义例外:用于处理预定义例外不能处理的例外;
自定义例外:用于处理与oracle 错误无关的其他情况;

declare
i caozyxx.caozyxm%type;
begin
select caozyxm into i from caozyxx where caozyxdm = &a;
dbms_output.put_line(i);
end;

no_data_found:如果我们输入了一个表中存在的条件,那么一切正常,但是如果我们输入了不存在的或者错误的条件,在没有例外的情况下,就会报错,我们可以这样处理:

declare
i caozyxx.caozyxm%type;
begin
select caozyxm into i from caozyxx where caozyxdm = &a;
dbms_output.put_line(i);
exception
when no_data_found then
dbms_output.put_line('输入错误'); 
end;

这样的话,如果输入了错误的条件,就会提示输入错误;
介绍几个常见例外:
case_not_found:在开发中,如果在when子句中没有包含必须的条件分子,就会触发case_not_found的例外,
既如果查询到的结果不包含在case语句的条件内,那么就会提示这个例外
案例:

create or replace procedure sp_pro(spno number) is
sno caozyxx.caozydm%type;
begin 
select caozydm into sno from caozyxx where caozydm = spno;
when sno<0100 then
 dbms_output.put_line('1111'); 
 wher sno<0200 then
  dbms_output.put_line('2222');
  end case;
  exception
  when case_not_found then
   dbms_output.put_line('case语句没有与条件相匹配的');
  end;

cursor_already_open:当重新打开已经打开的游标时,会隐含的触发例外

declare 
cursor sp_cursor is select caozyxm from caozyxx;
begin
open sp_sursor;--打开游标
for a in sp_sursor loop --又打开一次
dbms_output.put_line('a.caozyxm');
end loop;
exception
when cursor_already_open then
dbms_output.put_line('游标已经打开');
end;

这样就会提示游标已经打开;

dup_val_on_index: 在唯一索引所对应的列上插入重复的值时,会隐含触发

begin
insert into caozyxx(caozydm,caozyxm,mim,qiy,pinym) values('0000','公关部',null,1,'GGB');
exception
when dup_val_on_index then
dbms_output.put_line('在caozydm上不能出现重复值');
end;

invaild_cursor:当试图在不合法的游标上执行操作时,会触犯该例外;
例:试图从没有打开的游标提取数据,或是关闭没有打开的游标,则会触发该例外

declare
--定义游标类型
type sp_cursor is ref cursor;
--定义一个游标变量;
aa sp_cursor;
--定义变量
v_name caozyxx.caozyxm%type;
v_mim caozyxx.mim%type;
begin
--执行
--把aa和一个select结合;
--打开游标
open aa for select caozyxm,mim from caozyxx where qiy = 1;
close aa;--关闭游标
--循环取出
loop
  fetch aa into v_name,v_mim;
  --判断aa是否为空
  exit when aa%notfound;
  dbms_output.put_line('姓名:'||v_name||'薪水:'||v_mim);
end loop;
exception
when invalid_cursor then
dbms_output.put_line('请检查游标是否打开');
end;

invalid_number:当输入的数据有误时,会触发该例外

begin
update caozyxx set qiy = qiy+'a';
exception
when invalid_number then
dbms_output.put_line('输入的数字不正确');
end;

too_many_rows:当执行select into 语句时,如果返回超过了一行,则会触发该例外;

declare
a caozyxx.caozyxm%type;
begin
select caozyxm into a from caozyxx;
exception
when too_many_rows then
 dbms_output.put_line('多行数据');
 end;

zero_divide:当执行运算操作的时候,比如2/0时,会触发例外;

declare
a number(10);
begin
a:=10/0;
exception
when zero_divide then
dbms_output.put_line('分子不能为0');
end;

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

declare
a number(1);
begin
a:=700/2;
exception
when value_error then
dbms_output.put_line('值太大');
end;

其他预定义例外
1、login_denide
当用户非法登录时,触发:比如登录密码输入错误
2、not_logged_on
用户没有登录就执行dml操作,触发
3、storage_error
超出内存空间或内存被损坏,触发
4、timeout_on_resource
等待时超时,触发

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

自定义例外
预定义和非预定义例外都是oracle错误相关的,并且出现的oracle错误会隐含的触发相应的例外,而自定义例外与oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外;
案例:接收一个雇员编号,并把qiy加一,如果不存在该雇员,请提示:

create or replace procedure ex_test(a caozyxx.caozydm%type)
is
    begin
    update caozyxx set qiy = qiy+1 where caozydm = a;
    --与no_data_found区别,no_data_found的报错是在执行select语句,没有查询到数据会报错,在此是修改更新,oracle默认是不会报错的;
    end;

以上输入了不存在的编号,oracle默认是不会报错的,但如果我们想让他提示,就需要自定义一个例外:
自定义例外

create or replace procedure ex_test(a caozyxx.caozydm%type)
	is
	--自定义例外
	myex exception;
    begin
    update caozyxx set qiy = qiy+1 where caozydm = a;
    if sql%notfound then
    raise myex;
    --sql%notfound这是表示没有update
    --raise myex 触发myex 例外
    end if;
    exception
    when myex then
    dbms_output.put_line('没有更新任何数据');
     when  others then
  		dbms_output.put_line('没有更新任何数据');
    end;
    --when others then
    --我们知道,oracle预定义了许多例外,但是如果我们不清楚程序以后会出现哪些例外,或者我们不想分类这么清楚,只要触发了例外,就要捕获,这时我们就要用when others then ,通常放在例外的最后面
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值