1.常见的内置异常
常见的预定义异常以及抛出它们的方式:
(1)NO_DATA_FOUND : 当没有调用分组函数(例如:SUM或者COUNT等)时,SELECT INTO 语句没有返回任何数据行,此时就会抛出这个异常。例如,假设对EM表执行SELECT INTO语句,其中查询语句中EMPNO等于110。如果EMP表中没有EMPNO等于110的记录,则会抛出这个异常。当SELECT INTO语句调某分组函数,例如COUNT,结果集永远不会为空。因此,调用分组函数的SELECT INTO 语句永远不会抛出NO_DATA_FOUND异常。
(2)TOO_MANY_ROWS :当SELECT INTO 语句返回多个数据行的时候,就会抛出这个异常。根据定义,SELECT INTO只能返回一个数据行,
(3)ZERO_DIVIDE : 当除数为0的时候会抛出这个异常。
(4)LOGIN_DENIED :当用户尝试使用无效的用户名或者密码登录的时候,会抛出这个异常。
(5)PROGRAM_ERROR :当PL/SQL程序存在某个内部的问题时,就会抛出这个异常。
(6)VALUE_ERROR :当出现类型转换或者大小匹配错误的时候,就会抛出这个异常。
(7)DUE_VALUE_ON_INDEX :当程序在尝试定义唯一性索引的数据列中保存重复值时,就会抛出这个异常。例如,表cust_info的cust_no列上存在主键约束,那么往表cust_info中插入已经存在的cust_no的时候,则会抛出这个异常。
(8)OTHERS :不知道程序会出什么异常的情况下,使用这个。但是,在很多情况下中,你会发现很多程序使用这个异常处理程序,不会给你和用户带来有价值的信息,你也许不知道发生了什么错误。
- 异常处理的意义在于:提高用户体验,不让程序非正常终止。
- 当抛出内置异常的错误发生时,这种异常被称为隐式抛出。
2.案例:除数为0的异常处理
-- 除数为0的异常处理
DECLARE
v_num1 NUMBER := &input_num1;
v_num2 NUMBER := &input_num2;
v_result NUMBER;
BEGIN
v_result := v_num1 / v_num2;
DBMS_OUTPUT.PUT_LINE('v_result的值是:' || v_result);
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('除数为0了,同志,数学没学好吗?');
END;
3.案例:VALUE_ERROR异常
-- 计算某数的算术平方根
DECLARE
v_num number := &input_num;
BEGIN
DBMS_OUTPUT.PUT_LINE(v_num || ' 的算是平方根为:' || sqrt(v_num));
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('值出现错了!老铁');
END;
4.同时处理多种异常
-- 准备环境
create table tb(id number,name varchar2(10),class_no number);
insert into tb values(1, 'Jack1', 10);
insert into tb values(2, 'Jack2', 20);
insert into tb values(3, 'Jack3', 20);
insert into tb values(4, 'Jack4', 30);
commit;
-- PL/SQL块
DECLARE
v_class_no number := &input_class_no;
v_id tb.id%type;
v_name tb.name%type;
BEGIN
SELECT id, name
INTO v_id, v_name
FROM tb where class_no = v_class_no;
DBMS_OUTPUT.PUT_LINE('ID值为:' || v_id || ', name值为:' || v_name);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('返回的多余一条记录了!');
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('找不到记录!');
END;
输入值为10的时候,结果如下:
输入值为20的时候,结果如下:
输入值为40的时候,结果如下: