窗外冬雨悉悉索索,寒舍键盘噼里啪啦,喝着咖啡学Oracle,心情还算不错!
--20170107
--16.3 处理异常
--16.3.1 使用When子句
--代码16.10 使用When子句处理异常
DECLARE
e_nocomm EXCEPTION; --自定义的异常
v_comm NUMBER (10, 2); --临时保存提成数据的变量
v_empno NUMBER (4) := &empno; --从替换变量中获取员工信息
BEGIN
SELECT comm INTO v_comm FROM emp WHERE empno = v_empno; --查询并获取员工提成
IF v_comm IS NULL --如果没有提成
THEN
RAISE e_nocomm; --触发异常
END IF;
EXCEPTION
WHEN e_nocomm THEN --处理自定义异常
DBMS_OUTPUT.put_line ('选择的员工没有提成!');
--WHEN e_nocomm THEN --一个异常只能在When子句中出现一次,否则,会抛出PLS-00483异常
--DBMS_OUTPUT.put_line ('选择的员工没有提成!');
WHEN NO_DATA_FOUND OR TOO_MANY_ROWS THEN --处理处理多个异常
DBMS_OUTPUT.put_line ('没有找到任何数据或找到了多行数据!');
WHEN OTHERS THEN --处理预定义异常
DBMS_OUTPUT.put_line ('任何其他未处理的异常');
END;
select * from emp where empno=5093;
--16.3.2 使用Others异常处理器
--代码16.11 使用When Others Then异常处理器
DROP TABLE tbl_errors; --先删除异常日志表
CREATE SEQUENCE err_seq; --创建一个序列,用来为tbl_errors生成主键
CREATE TABLE tbl_errors ( --异常记录表
error_id NUMBER PRIMARY KEY, --主键id
prog_name VARCHAR2(200), --错误触发的程序名称
code NUMBER, --错误编号
message VARCHAR2(64), --错误消息
error_date DATE DEFAULT SYSDATE --错误发生的时间
);
--创建一个子程序,用来记录错误日志
CREATE OR REPLACE PROCEDURE log_errors(p_code NUMBER,p_message VARCHAR2,p_prog_name VARCHAR2)
AS
PRAGMA AUTONOMOUS_TRANSACTION; --这是一个自治事务的过程,可以单独使用COMMIT和ROLLBACK
BEGIN
--向tbl_errors表中插入错误信息
INSERT INTO tbl_errors VALUES(err_seq.NEXTVAL,p_prog_name,p_code,p_message,SYSDATE);
COMMIT; --提交事务
EXCEPTION
WHEN OTHERS THEN --如果出现任何异常则回滚事务
ROLLBACK;
END;
--使用WHEN OTHERS THEN异常处理器的示例,它用来记录错误信息
CREATE OR REPLACE PROCEDURE others_exception_demo
AUTHID DEFINER AS
v_name scott.emp.ename%TYPE;
v_code NUMBER;
v_errm VARCHAR2(64);
BEGIN
SELECT ename INTO v_name
FROM scott.emp
WHERE empno = -1; --这里故意制造了一个NO_DATA_FOUND的异常
EXCEPTION
WHEN OTHERS THEN --在WHEN OTHERS THEN中处理异常
v_code := SQLCODE;
v_errm := SUBSTR(SQLERRM, 1, 64);
DBMS_OUTPUT.PUT_LINE
('错误代码: ' || v_code || ': ' || v_errm);
log_errors(v_code,v_errm,'scott.others_exception_demo');--记录错误消息
--RAISE; --重新抛出异常
END;
/
BEGIN
others_exception_demo;
END;
select * from tbl_errors;
drop table tbl_errors;
--16.3.3 使用SQLCODE和SQLERRM
--代码16.12 调用SQLERRM函数
BEGIN
--使用带参数的SQLERRM输出错误消息
DBMS_OUTPUT.PUT_LINE('SQLERRM(0):' || SQLERRM(0));
DBMS_OUTPUT.PUT_LINE('SQLERRM(100):' || SQLERRM(100));
DBMS_OUTPUT.PUT_LINE('SQLERRM(10):' || SQLERRM(10));
DBMS_OUTPUT.PUT_LINE('SQLERRM:' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLERRM(-1):' || SQLERRM(-1));
DBMS_OUTPUT.PUT_LINE('SQLERRM(-54):' || SQLERRM(-54));
END;
/