DBMS_ERRLOG 包

DBMS_ERRLOG 包提供一种方法给指定表创建对应的错误日志表。

创建错误日志表的方法有两种,一是通过 DBMS_ERRLOG 包中的 CREATE_ERROR_LOG 来创建,二是通过 SQL 语法手动创建。因为使用 DBMS_ERRLOG 包创建错误日志表简单易行,建议用户使用方法一。

42.1 相关方法

给指定表创建对应的错误日志表。不支持指定表中含有列类型为 LONG、CLOB、 BLOB、 BFILE 的列。也不支持指定的表中和要创建的错误日志表含有同名列。

语法如下:

PROCEDURE CREATE_ERROR_LOG(

  DML_TABLE_NAME     IN VARCHAR,

  ERR_LOG_TABLE_NAME   IN VARCHAR DEFAULT NULL,

  ERR_LOG_TABLE_OWNER  IN VARCHAR DEFAULT NULL,

  ERR_LOG_TABLE_SPACE  IN VARCHAR DEFAULT NULL,

  SKIP_UNSUPPORTED    IN BOOLEAN DEFAULT FALSE

);

参数详解

● DML_TABLE_NAME 输入参数, 错误日志记录表所基于的数据库表,支持以前缀形式指定其他用户的表。

● ERR_LOG_TABLE_NAME 输入参数, 用户创建的错误日志记录表的名字,默认使用数据库表名加上前缀’ERR$_’。错误日志记录表结构如下:

序号 数据类型 说明
1 DM_ERR_NUMBER$ NUMBER 错误码
2 DM_ERR_MESG$ VARCHAR2(2000) 错误信息
3 DM_ERR_ROWID$ BIGINT 保存出错的行号,insert 时为空值
4 DM_ERR_OPTYP$ VARCHAR2(2) 出错的 dml 类型, I 表示插入, U 表示更新, D 表示删除
5 DM_ERR_TAG$ VARCHAR2(2000) log errors 语法(expression)设定的值, 未设置时为空

通过 SQL 语法手动创建错误日志表(例如,表名为 LOG_T1)。为了减少出错环节,不推荐用户自己手动创建。

create table LOG_T1(

DM_ERR_NUMBER$ NUMBER,

DM_ERR_MESG$ VARCHAR2(2000 BYTE),

DM_ERR_ROWID$ BIGINT,

DM_ERR_OPTYP$ VARCHAR2(2 BYTE),

DM_ERR_TAG$ VARCHAR2(2000 BYTE));

● ERR_LOG_TABLE_OWNER 输入参数,错误日志记录表的拥有者,默认使用当前连接的用户。

● ERR_LOG_TABLE_SPACE 输入参数,错误日志记录表所在的表空间,需要有权限,默认使用当前用户使用的表空间。

● SKIP_UNSUPPORTED 输入参数,设置为 TRUE 时,列类型不支持的将会被跳过并且不会添加到错误日志记录表,设置为 FALSE 时,一个不支持的列类型将会引发过程中断,默认为 FALSE。

42.2 使用说明

  1. 使用该包需要有包执行权限,表的操作权限,建表权限。
  2. 支持对日志表进行 I/D/U 操作。
  3. 暂时不支持对视图建错误日志表。
  4. 暂时不支持临时表和 HUGE 表。
  5. 暂时不支持批量绑定参数执行*<*log erros> 语法。
  6. 只有错误发生在 I/D/U 的自身操作符执行期间才会记录日志。
  7. 部分错误在进行错误日志记录时无法登记数据,如字符串转换出错。
  8. 暂不支持错误日志表中存在二级索引、约束、触发器。
  9. 暂时不支持 INSERT ALL 语句中使用*<*log erros> 语法。
  10. 虚拟列暂不进行记录数据。
  11. 暂时不支持 DBLINK。

42.3 使用错误日志表

在数据插入语句、数据修改语句或数据删除语句的尾部使用*<*log errors>,可以将错误操作生成错误记录,登记到错误日志表中。

log errors 语法:

<数据插入语句><log errors>;

<数据修改语句><log errors>;

<数据删除语句><log errors>;

<log errors>::=LOG ERRORS [INTO <表名>][(<expression>)] REJECT LIMIT <UNLIMITED | <错误行数>>

<数据插入语句>::=请参考《DM8_SQL语言使用手册》第5.1节

<数据修改语句>::=请参考《DM8_SQL语言使用手册》第5.2节

<数据删除语句>::=请参考《DM8_SQL语言使用手册》第5.3节

参数详解

● [INTO < 表名 >] 错误日志表的表名。缺省使用的是默认错误日志表名。

● *<expression> 是一个表达式,为错误日志记录的一个标记,即每一行错误日志会有一列存储此列表达式的值,该 <*expression> 需要是字符串或者是可以转换为字符串的内容。

● REJECT LIMIT <UNLIMITED | < 错误行数 >> 指定允许的最大错误行数。UNLIMITED 表示没有限制;< 错误行数 > 指定的允许的最大错误行数,取值(0~ 2147483647),超过此值将回滚 DML 操作,但仍保留已经生成的错误日志。错误日志表生成记录后,不会因为 DML 语句的回滚而回滚,也不会因为基表被删除而同步被删除。其中,空间不足导致的回滚,不会在错误日志表中记录回滚记录。 针对不同的 DML 操作,错误日志表中记录的错误类型如下表所示:

DML 操作 字符串转换出错 违反唯一约束条件 不允许 NULL 值 数据超过数据类型限制 分区列更新将引起分区的更 插入值不满足分区范围
INSERT 支持 支持 支持 支持 × 支持
UPDATE × × 支持 支持 支持 ×
DELETE × × × × × ×

注:符号“×”表示错误日志表中暂不支持记录该报错信息

42.4 举例说明

首先,创建数据库表 t1,并使用 DBMS_ERRLOG 为 t1 创建一个错误日志表。同时插入 3 条数据。

create table t1 (id int primary key,name varchar(20));

begin  

 DBMS_ERRLOG.CREATE_ERROR_LOG('T1','LOG_T1');

end;

/

insert into t1 values(1, 'a');

insert into t1 values(2, 'b');

insert into t1 values(10, 'j');

其次,在插入数据的时候使用*<*log errors>。为 t1 插入 20 条数据,其中有三条是违反了唯一性约束的。

begin

 for i in 1..20 loop

   insert into t1 values(i,i) LOG ERRORS INTO LOG_T1 ('INSERT ERROR') REJECT LIMIT UNLIMITED;

 end loop;

 commit;

end;

/

然后,查看日志信息表。

select * from LOG_T1;

查询结果:

行号 DM_ERR_NUMBER$ DM_ERR_MESG$ DM_ERR_ROWID$ DM_ERR_OPTYPE$ DM_ERR_TAG$ ID NAME
1 -6602 违反表[T11]唯一性约束 0 I INSERT ERROR 1 1
2 -6602 违反表[T11]唯一性约束 0 I INSERT ERROR 2 2
3 -6602 违反表[T11]唯一性约束 0 I INSERT ERROR 10 10

可见,LOG_T1 中记录了插入失败的数据以及相关信息。

select count(*) from t1;

查询结果:20。

可见,t1 中插入了全部未出错的数据。之前的 3 条和后来批量插入的 17 条。

微信扫码
分享文档
扫一扫
联系客服