一个优秀的程序都应该能够正确的处理各种出错异常,并尽可能的从错误中恢复,ORACLE提供异常来实现错误处理,异常exception这个词还是这个,处理正常执行过程中未预料的事件,他分为预定义的错误,和自定义的错误,相当于还可以自定义一个异常,由于PL/SQL块一旦产生异常,没有指出如何处理,程序就会自动的终止程序的运行,自动终止程序的运行,就像JAVA里面也是一样的,他这里有三种异常的错误,第一种叫预定义的,预定义的大概有24种异常,然后这个时候它会自动的给你抛出来如果你不使用exception给他捕获的话,那他就在这里停止了,如果你要捕获,你就使用exception给他处理一下,这跟JAVA是一样的,非预定义的异常,就是其他标准的ORACLE错误,也是ORACLE指定的一个错误,但是他这个错误和你自己定义的错误,来练习起来,然后自定义一个名,我们来说这两个怎么来写,比如我想查询一个人的工资,如果查工资低于2千,工资太低本来没有啥问题,你只要这个工资低于多少钱,我就让你抛一个异常,就是你可以自定义一个异常,然后异常的格式,在大的PL/SQL块里边,叫exception,在这里边写,如何处理这个异常,当时这个类型的时候,then如何处理,当你有多个异常,when then,when other 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;
我使用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;
这里就相当于子程序来执行,只要你执行到哪一块出现异常了,我就去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;
在这儿,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;