异常处理
定义
在程序运行过程中出现的错误叫异常,包括程序,软件,硬件,网络等
系统异常
NO_DATA_FOUND 未找到数据
ZERO_DIVIDE 除数不能为零
TO_MANY_ROWS 返回结果超出一行
自定义异常
定义
变量名 EXCEPTION
抛出异常
抛出异常就是让程序故意报出一个错误
如何抛出一个异常
RAISE 异常变量;--方法一
DBMS_STANDARD.RAISE_APPLICATION_ERROR(异常编码,'异常信息');--方法二
方法一:
DECLARE
EXC EXCEPTION;--声明一个异常变量(自定义一个异常)
BEGIN
RAISE EXC;
END;
方法二:
BEGIN
DBMS_STANDARD.RAISE_APPLICATION_ERROR(-20010,'我的异常');
END;
捕获异常
BEGIN
EXCEPTION
异常处理部分
WHEN 异常名称 THEN
处理代码;
WHEN 异常名称 THEN
处理代码;
[WHEN OTHERS THEN
处理代码;]
END;
作用
通过异常处理,让出现错误的代码回滚,并且记录错误日志
DECLARE
V VARCHAR2(30);
BEGIN
SELECT ENAME INTO V FROM EMP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('捕获到了异常');
END;
*系统异常变量
SQLCODE
获取异常的编码
注意:
NO_DATA_FOUND 的异常编码是100,不是ORA-01403
SQLERRM
获取异常信息
举例:
DECLARE
V VARCHAR2(30);
BEGIN
SELECT ENAME INTO V FROM EMP WHERE 1=0;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
DBMS_OUTPUT.PUT_LINE('这里也是异常处理代码,没有异常就不执行');
END;
注意:
EXCEPTION 和END 之间的代码都是异常处理代码
为了解决上述问题:代码子块的妙用;
DECLARE
V VARCHAR2(30);
BEGIN
BEGIN
SELECT ENAME INTO V FROM EMP WHERE EMPNO=7369;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
DBMS_OUTPUT.PUT_LINE('这里的代码是不管异常发生与否都会执行的代码');
END;
异常绑定
将一个异常绑定到自定义异常变量上(绑定之后,可以通过自定义异常变量来捕获该异常)
给已经存在的异常编码给他一个自定义的异常变量名称
BEGIN
INSERT INTO DEPT VALUESS(10,'DEPT','LOC');
--不知道这里的异常的名字,可以给他起一个名字
EXCEPTION
WHEN OTHERS THEN
END;
语法
DECLARE
异常变量 EXCEPTION;
PRAGMA EXCEPTION_INIT(异常变量,异常编码);
BEGIN
END;
举例:将-00001的异常和名为EXC的异常变量绑定
DECLARE
EXC EXCEPTION;
PRAGMA EXCEPTION_INIT(EXC,-00001);
BEGIN
INSERT INTO DEPT VALUES(10,'DEPT','LOC');
EXCEPTION
WHEN EXC THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
→
起名字的目的呢,就是方便捕获
回滚事务
DECLARE
EXC EXCEPTION;
PRAGMA EXCEPTION_INIT(EXC,-00001);
BEGIN
INSERT INTO DEPT VALUES(10,'DEPT','LOC');
COMMIT;
EXCEPTION
WHEN EXC THEN
ROLLBACK;--事务回滚
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
业务异常或应用异常
DBMS_STANDARD.RAISE_APPLICATION_ERROR(自定义异常编码,异常信息,布尔类型(TRUE就是替换为20000以下的系统异常));
↑业务异常或应用异常
自定义异常编码:范围 -20000 ~ -20999
文件读写
DIRECTORY 目录对象
CREATE DIRECTORY 目录名称 AS '文件路径'
GRANT CREATE ANY DIRECTORY TO SCOTT;
UTL_FILE.FILE_TYPE:文件类型
UTL_FILE.FOPEN('目录名称','文件名','读写方式'):打开文件的方法
目录名称:为DIRECTORY 对象名字,必须全部大写
文件名:1.TXT
读写方式:
r:表示读
w
a:表示追加
UTL_FILE.PUT_LINE(文件变量,要写入的内容):向文件中写入内容
UTL_FILE.GET_LINE(文件变量,字符串变量):从文件中读取一行内容,将读取的内容放
UTL_FILE.FCLOSE(文件变量):关闭文件
DECLARE
F UTL_FILE.FILE_TYPE ;
BEGIN
--打开文件
F:=UTL_FILE.FOPEN('FILEPATH','TEST.TXT','W');
UTL_FILE.PUT_LINE(F,'Hello');
UTL_FILE.PUT_LINE(F,'SMITH');
--关闭文件
UTL_FILE.FCLOSE(F);
END;
举例:
写一个代码块将emp表中中的全部员工的姓名写入文件
DECLARE
F UTL_FILE.FILE_TYPE;
BEGIN
F:=UTL_FILE.FOPEN('FILEPATH','NAMES.TXT','W');
FOR V IN (SELECT ENAME FROM EMP ) LOOP
UTL_FILE.PUT_LINE(F,V.ENAME);
END LOOP;
UTL_FILE.FCLOSE(F);
END;
举例:文件的追加
DECLARE
F UTL_FILE.FILE_TYPE;
BEGIN
F:=UTL_FILE.FOPEN('FILEPATH','TEST.TXT','A');
FOR V IN (SELECT ENAME FROM EMP ) LOOP
UTL_FILE.PUT_LINE(F,V.ENAME);
END LOOP;
UTL_FILE.FCLOSE(F);
END;
NULL:它是一个空语句,只用来占位,不做任何操作
BEGIN
NULL;
END;
举例:读文件需要使用NO_DATA_FOUND异常来结束