DML ERROR LOGGING总结
总结:康标
email:kang_biao@hotmail.com
[@more@]DML ERROR LOGGING总结
总结:康标
email:kang_biao@hotmail.com
为什么要使用DML ERROR LOGGING?
在Oracle 10之前执行一些大规模的操作的时候,尤其是一些长时间bulk DML操作的时候,会发现如果在执行过程中如果有一行发生错误的时候,就会放弃这个DML操作而回滚。这样的话就会浪费大量的时间和系统资源。是不是能有一种途径使得在执行bulk DML操作,将成功的部分插入到表中,而将未能正确插入的部分的错误插入到其他表中,以后来处理。
在Oracle 10g release 2:中引入了一个特性:DML ERROR LOGGING这个特性就能够实现以上的功能。
添加一个ERROR-LOGGING表
添加ERROR-LOGGING表需要使用的是包DBMS_ERRLOG这个包。这个表在Oracle 10g中只有一个过程:CREATE_ERROR_LOG。
DBMS_ERRLOG.CREATE_ERROR_LOG ( dml_table_name IN VARCHAR2, err_log_table_name IN VARCHAR2 := NULL, err_log_table_owner IN VARCHAR2 := NULL, err_log_table_space IN VARCHAR2 := NULL, skip_unsupported IN BOOLEAN := FALSE); |
这里指定的有两个表名,一个是DML处理的表名。一个是建立这个ERROR-LOGGING表名。
建立一个表:
SQL> create table dml(a varchar2(2) primary key,b varchar2(1)); 表已创建。 |
建立一个ERROR LOGGING表
SQL> exec dbms_errlog.create_error_log('DML','DML_LOG'); PL/SQL 过程已成功完成。 |
看看这个表都是有什么?
SQL> desc dml_log 名称 是否为空? 类型 ----------------------------------------- -------- ----------------- ORA_ERR_NUMBER$ NUMBER ORA_ERR_MESG$ VARCHAR2(2000) ORA_ERR_ROWID$ ROWID ORA_ERR_OPTYP$ VARCHAR2(2) ORA_ERR_TAG$ VARCHAR2(2000) A VARCHAR2(4000) B VARCHAR2(4000) |
这时候会发现这个表中有两部分:
固定部分:
ORA_ERR_NUMBER$ NUMBER ORA_ERR_MESG$ VARCHAR2(2000) ORA_ERR_ROWID$ ROWID ORA_ERR_OPTYP$ VARCHAR2(2) ORA_ERR_TAG$ VARCHAR2(2000) |
ORA_ERR_NUMBER$
Oracle的错误号。
ORA_ERR_MESG$
Oracle错误信息文本。
ORA_ERR_ROWID$
Oracle的错误行ROWID。(UPDATE、DELETE)
ORA_ERR_OPTYP$
操作类型(INSERT UPDATE/DELETE)
ORA_ERR_TAG$
用户支持标签
可变部分:
A VARCHAR2(4000) B VARCHAR2(4000) |
使用方法:
使用方法其实很简单。
LOG ERRORS [INTO schema.table] [ (simple_expression) [ REJECT LIMIT {integer|UNLIMITED} ] |
看看错误的产生:
SQL> insert into dml select rownum,rownum from all_objects where rownum < 11; insert into dml select rownum,rownum from all_objects where rownum < 11 * 第 1 行出现错误: ORA-12899: 列 "TEST"."DML"."B" 的值太大 (实际值: 2, 最大值: 1) SQL> select * from dml; 未选定行 |
如果这样使用看看效果。
SQL> insert into dml 2 select rownum,rownum from all_objects where rownum < 11 3 log errors into dml_log ('my_log') reject limit 10; 已创建9行。 |
没有出现问题,看看log表中都是什么东西:
SQL> select * from dml_log; ORA_ERR_NUMBER$ ORA_ERR_MESG$ ORA_ERR_ROWID$ ORA_ERR_OPTYP$ ORA_ERR_TAG$ A B --------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 12899 ORA-12899: 列 "TEST"."DML"."B" 的值太大 (实际值: 2, 最大值: 1) I my_log 10 10 |
这里面会发现存放着错误的信息。已经错误发生的值。
需要注意的问题:
1、所有类型的DML操作都能够被记录在日志中。
2、每一个ERROR LOGGING表对于一个特定的操作表。两种表之间是一一对应的。不能被混用。
3、被记录的类型是:
值太大。
约束问题
由触发器产生的错误
类型转换
分区映射
4、LONG/CLOB/BLOB/BFILE/ADTs不能为error-logging表的一部分。
5、多次重复出现错误的时候,信息会被重复记录在表中,需要在执行之前删除表。
SQL> insert into dml 2 select rownum,rownum from all_objects where rownum < 11 3 log errors into dml_log ('my_log') reject limit 10; 已创建0行。 SQL> select count(*) from dml_log; COUNT(*) ---------- 11 |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/222350/viewspace-914775/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/222350/viewspace-914775/