异常和文件读写

异常

简介

在编写程序的过程中,总会遇到不少的错误
异常包含软件,硬件,网络,程序等运行过程中出现的错误

分类
这些错误有的是由于错误的输入造成的,有的是程序在运行过程中出现的逻辑性存错
oracle中的错误可以分为如下两大类

  • 编译时错误:
    • 程序在编写过程中出现的错误,pl/sql引擎在进行编译时会发现这些错误
    • 并报告给用户,此时程序还没有完全运行
  • 运行时错误:
    • 程序在运行过程中因为各种各样的原因产生的运行时错误,
    • 由于这些错误有时难以预料,因此需要异常处理机制来进行处理

一般在使用时分为两种情况

  • 记录错误日志
  • 将错误前和错误后,修改前和修改后的记录保存到日志中

内置异常

异常名 异常编号 异常描述
ACCESS_INTO_NULL: 对应ORA-06530 为了引用对象属性,必须首先初始化对象。直接引用未初始化的对象属性时,会发生异常
CASE_NOT_FOUND: 对应ORA-06592, 当CASE语句的WHEN子句没有包含必须条件分支或者ELSE子句时,会触发
COLLECTION_IS_NULL: 对应ORA-06531, 在给嵌套表变量或者varrary变量赋值之前,必须首先初始化集合
CURSOR_ALREADY_OPEN: ORA-06511, 当已打开游标上执行OPEN操作时会触发
INVALID_CURSOR: ORA-01001, 当试图从未打开游标,提取数据,或者关闭未打开游标时会触发
INVALID_NUMBER: ORA-01722, 当内嵌SQL语句不能将字符转变成数字时会触发
LOGIN_DENIED: ORA-01017, 连接Oracle数据库时,如果提供了不正解的用户名和口令时会触发
NO_DATA_FOUND: ORA-01403 执行SELECT INTO 未返回行或者引用了未初始化的PL/SQL表元素时会触发
NOT_LOGGED_ON: ORA-01012 没有连接数据库执行SQL时会触发
PROGRAM_ERROR: ORA-06501 存在PL/SQL内部问题,在这种情况下需要重新安装数据字典视图和PL/SQL包
ROWTYPE_MISMATCH: ORA-016504 当执行赋值操作时,如果宿主变量和游标变量不兼容的返回类型时,会触发
SELF_IS_NULL: ORA-30625, 当使用对象类型时,如果在null实例上调用成员方法时,会触发
STORAGE_ERROR: ORA-06500 当执行PL/SQL块时,如果超出内存空间或者内存被破坏,会触发
SUBSCRIPT_BEYOND_COUNT: ORA-06533 当使用嵌套或者varray元素的范围进会触发
SUBSCRIPT_OUTSIDE_LIMIT: ORA-06532, 使用嵌套表或者varray元素时,如果元素下标为负值时,会触发
SYS_INVALID_ROWID: ORA-01410 当字符串转变为ROWID时如果使用了无效字符串,会触发
TIMEOUT_ON_RESOURCE: ORA-00051 当等待资源时如果出现超时会触发
TOO_MANY_ROWS: ORA-01422 当执行SELECT INTO时,如果返回超过一行、会触发
VALUE_ERROR: ORA-06502, 执行赋值时,如果变量长度不足,会触发
ZERO_DIVIDE: ORA-01476 如果用数字值除0,会触发

异常的使用方式

带异常处理的代码块

declare
  声明部分
begin
  代码块
  exception
    异常处理部分
end;

异常处理代码块

exception
  when 异常名称 then
    异常处理代码;
  when 异常名称 then
    异常处理代码;
  ...
  when others then
    异常处理代码;

异常的使用方式:抛出异常,捕获异常

others可以捕获到任何异常

捕获异常

exception中的语法叫做捕获异常

declare 
  --声明一个emp表的rowtype类型变量
  v emp%rowtype;
begin
  select * into v from emp where deptno=1;
  dbms_output.put_line('hexo');
  exception
    when no_data_found then
      dbms_output.put_line('未找到数据');
end;

输出结果

未找到数据

当程序出现异常时,会跳到exception代码块.错误代码和exception之间的代码不会执行

oracle内置的异常变量

  • sqlcode: 异常编码
    • 100表示no_data_found
    • 1表示用户自定义异常
    • -1表示系统内置异常
  • sqlerrm: 异常信息
declare
  --声明一个emp表的rowrtpe类型变量
  v emp%rowtype;
begin
  begin
    select * into v from emp where empno=1;
    exception
      when others then
        dbms_output.put_line(sqlcode);
        dbms_output.put_line(sqlerrm);
  end;
  dbms_output.put_line('next');
end;

输出

100
ORA-01403: 未找到任何数据
next

抛出异常/自定义异常

定义异常
异常名称 exception;

抛出异常
raise 异常名称;

declare
  --定义一个异常
  myexc exception;
begin 
  --抛出自定义异常
  raise myexc;
  --捕获异常
  exception
    when myexc then
      dbms_output.put_line(sqlcode);
      dbms_output.put_line(sqlerrm);
end;

输出

1
User-Defined Exception

另一个抛出异常的方式

dbms_standard.raise_application_error(异常编码,'异常信息')
抛出一个应用异常(业务异常)
异常编码范围: -20000 ~ -20999

begin
  dbms_standard.raise_application_error(-20001,'俺的异常');
  exception
    when others then
      dbms_output.put_line(sqlcode);
      dbms_output.put_line(sqlerrm);
end;

输出

-20001
ORA-20001: 俺的异常

异常绑定

通过自定义异常绑定没有名字的异常
语法

pragma exception_init(自定义异常名,异常编码);--声明部分写
declare
  --自定义一个异常
  myexc exception;
  --将-00001的异常绑定到自定义异常上
  pragma exception_init(myexc,-00001);
begin
  insert into dept values(10,'a','b');
  exception
    when myexc then
      dbms_output.put_line(sqlcode);
      dbms_output.put_line(sqlerrm);
end;

输出

-1
ORA-00001: 违反唯一约束条件 (SCOTT.PK_DEPT)
declare
  --自定义一个异常
  myexcs exception;
  --异常绑定
  pragma exception_init(myexcs,-20001);
begin
  dbms_standard.raise_application_error(-20001,'我的异常');
  exception
    when myexcs then
      dbms_output.put_line(sqlcode);
      dbms_output.put_line(sqlerrm);
end;

输出异常

-20001
ORA-20001: 我的异常

文件读写

读写文件方法

读写文件需要用到的包
utl_file

utl_file.file_type

作用:文件类型

utl_file.fopen('目录名称','文件名',读写方式)

作用:打开文件
目录名称:是oracle中directory对象名.使用时,目录名要大写

  create directory 目录名称 as '系统的文件路径';

如果创建目录提示权限不足,可以:

SQL> grant create any directory to scott;
授权成功。

读写方式

  • r 表示只读
  • w 表示写
  • a 表示追加

url_file.put_line(文件变量,写入的内容);

作用:向文件写入一行数据

utl_file.put_line(文件变量,字符串变量);

作用:将文件中的一行数据读取出来.保存到变量中.

utl_file.fclose(文件变量);

作用:关闭文件

写文件

创建一个目录

create directory filepath as 'D:\1122\test';
declare
  --声明文件变量
  f utl_file.file_type;
begin
  --打开文件,如果文件不存在,则创建,如果文件存在,则覆盖
  f:=utl_file.fopen('FILEPATH','1.txt','w');
  --向文件中写一行内容
  utl_file.put_line(f,'Hello World');
  --关闭文件
  utl_file.fclose(f);
end;

1.txt

Hello World

把emp表中所有员工编号写入文件

declare
  --声明一个文件变量
  f utl_file.file_type;
begin
  --打开文件
  f:=utl_file.fopen('FILEPATH','2.txt','w');
  for v in (select empno from emp) loop
    --将员工编号写入到文件中
    utl_file.put_line(f,v.empno);
  end loop;
  --关闭文件
  utl_file.fclose(f);
end;

2.txt

9123
7777
7369
7499
7521
7566
7654
7698
7782
7788
7839
7844
7876
7900
7902
7934

读文件

declare
  --定义一个文件变量
  f utl_file.file_type;
  --声明一个字符串变量保存文件的一行记录
  str varchar2(200);
begin 
  --打开文件
  f:=utl_file.fopen('FILEPATH','2.txt','r');
  --循环读取文件
  loop
    --读取文件的一行记录
    utl_file.get_line(f,str);
    --打印str变量
    dbms_output.put_line(str);
  end loop;
  --关闭文件
  utl_file.fclose(f);
end;

发现可以将文件内容正常输出到屏幕
但是还是报异常

ORA-01403: 未找到任何数据
ORA-06512: 在 "SYS.UTL_FILE", line 106
ORA-06512: 在 "SYS.UTL_FILE", line 746
ORA-06512: 在 line 12

文件读写中的异常处理

方法1

declare
  --定义一个文件变量
  f utl_file.file_type;
  --声明一个字符串变量保存文件的一行记录
  str varchar2(200);
begin 
  --打开文件
  f:=utl_file.fopen('FILEPATH','2.txt','r');
  loop
    begin
      --读取文件的一行记录
      utl_file.get_line(f,str);
      exception
        when no_data_found then
          exit;
    end;
    
    --打印str的值
    dbms_output.put_line(str);
  end loop;
  --关闭文件
  utl_file.fclose(f);
end;

方法2

declare
  --定义一个文件变量
  f utl_file.file_type;
  --声明一个字符串变量保存文件的一行记录
  str varchar2(200);
begin 
  --打开文件
  f:=utl_file.fopen('FILEPATH','2.txt','r');
  begin
    loop
      utl_file.get_line(f,str);
      --打印str的值
      dbms_output.put_line(str);
    end loop;
    exception
      when no_data_found then
        NULL; --占位
  end;
  --关闭文件
  utl_file.fclose(f);
end;
上一篇:泰坦尼克号生存预测-----基于决策树模型(机器学习- sklearn)


下一篇:基于机器学习的异常流量监测代码实现