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号的工资是24240declarev_salary employees.salary%type;beginselect salary into v_salary from employeeswhere employee_id = 100;dbms_output.put_line(v_salary);end;

这儿这个程序,我们写上也行,只是我们现在不知道这里面会出现什么异常,我们这里改成一个大于,这显然不是一个人的员工的查询结果了,正常我们要使用游标,这是多条记录,现在这里实际上是多条记录,实际返回的行数超出请求的行数declarev_salary employees.salary%type;beginselect salary into v_salaryfrom employeeswhere employee_id > 100;end;

too_many_rows这就是他错误的名字,错误的标号,那我在我相应的exception这里,when,叫to_many_rows,then,输出的行数太多了,就这样写,这不就执行了declarev_salary employees.salary%type;beginselect salary into v_salaryfrom employeeswhere employee_id > 100;dbms_output.put_line(v_salary);exceptionwhen too_many_rows then dbms_output.put_line('输出的行数太多了!!!!!');end;

输出的行数太多了,就这样写,相当于他抛出来这样一个对象一样,然后我们看这个对象对应的类型,是这个类型的你给他输出,你也可以给他补一下,when others then,出现其他类型的异常的时候,这个就叫预定义的异常,就是他出现异常的错误在这里面有标识了declarev_salary employees.salary%type;beginselect salary into v_salaryfrom employeeswhere 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,当你出现这个异常的时候,违反完整性约束条件,故不可以删除此用户,enddeclarev_deleteid_exception exception;pragma exception_init(e_deleteid_exception,-2292);begindelete from employees where employee_id = 100;exceptionwhen 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,打印,相当于你这个异常到底是干什么的,工资太高了,就这样一个,declaree_too_high_sal_exception;v_sal employees.salary%type;beginselect salary into v_sal from employees where employee_id = 100;if v_sal > 10000 thenraise e_too_high_sal;end if;exceptionwhen 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);
exceptionwhen 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);
exceptionwhen 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他就能够找到,他找到给他打印一下declarev_sal employees.salary%type;beginselect salary into v_sal from employees where employee_id = 100;dbms_output.put_line(v_sal);end;

这是他的工资,然后你要输出比如1001,这人不在,说未找到数据,这不就出现一个异常吗,ORA-1403,你在这找找declarev_sal employees.salary%type;beginselect salary from employees where employee_id = 1001;dbms_output.put_line(v_sal);end;

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

在这儿,exception,when,no_data_found,then,查无此人,那就这样子,这个就相当于叫预定义的declarev_sal employees.salary%type;beginselect salary into v_sal from employees where employee_id = 100;dbms_output.put_line(v_sal);exceptionwhen no_data_found then dbms_output.put_line('查无此人');end;

这个相当于是预定义的,还有对应的异常的类型,没有的话就自己造一个19. 更新指定员工工资,如工资小于300,则加100;对 NO_DATA_FOUND 异常, TOO_MANY_ROWS 进行处理.
declarev_sal employees.salary%type;
beginselect 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;
exceptionwhen 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,说明就没有异常declarev_sal employees.salary%type;beginselect 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;exceptionwhen 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);
begindelete from employees where employee_id = 100;exception--3. 处理异常when temp_exception thendbms_output.put_line('违反完整性约束!');
end;删除这个人,包2292这个异常,关联起来,然后在when这里接收21. 自定义异常: 更新指定员工工资,增加100;若该员工不存在则抛出用户自定义异常: no_resultdeclare--自定义异常                                   no_result exception;   
beginupdate employees set salary = salary + 100 where employee_id = 1001;--使用隐式游标, 抛出自定义异常if sql%notfound thenraise no_result;end if;  exception--处理程序抛出的异常when no_result thendbms_output.put_line('更新失败');
end;它使用用户自定义的,正常这个员工不存在的话,直接使用no_data_found就可以了,还有想用户自定义的也行,update employees set salary = salary + 100,当employee_id是他的时候,它使用的叫隐式游标,因为这个是异常数据,判断是否在,就raise一个异常,这个对象是我自定义的,我们看一下就行,更新失败declareno_result exception;beginupdate employees set salary = salary + 100 where employee_id = 100;if sql%notfound thenraise no_result;end if;exceptionwhen no_result thendbms_output.put_line('更新失败');end;


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部