Oracle10g新特性——记录DML错误日志(三)
来源:互联网 发布:淘宝怎么撤回退款申请 编辑:程序博客网 时间:2024/06/06 00:02
当一个DML运行的时候,如果遇到了错误,则这条语句会整个回滚,就好像没有执行过。不过对于一个大的DML而言,如果个别数据错误而导致整个语句的回滚,会浪费很多的资源和运行时间,从10g开始Oracle支持记录DML语句的错误,而允许语句自动继续执行。
这篇介绍DML记录语句不支持的数据类型。
Oracle10g新特性——记录DML错误日志(一):http://yangtingkun.itpub.net/post/468/479317
Oracle10g新特性——记录DML错误日志(二):http://yangtingkun.itpub.net/post/468/479366
除了上一篇文章介绍的不支持的操作外,DML记录错误语句还有一些不支持的数据类型,比如:LONG、LONG RAW、BLOG、CLOB、NCLOB、BFILE以及各种对象类型。
Oracle不支持这些类型的原因也很简单,这些特殊的类型不是包含了大量的记录,就是需要通过特殊的方法来读取,因此Oracle没有办法在SQL处理的时候将对应列的信息写到错误记录表中。
SQL> DROP TABLE T PURGE;
表已删除。
SQL> DROP TABLE T_ERROR_LOG PURGE;
表已删除。
SQL> CREATE TABLE T
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 RESUME CLOB);
表已创建。
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG('T', 'T_ERROR_LOG')
BEGIN DBMS_ERRLOG.CREATE_ERROR_LOG('T', 'T_ERROR_LOG'); END;
*第 1行出现错误:
ORA-20069: Unsupported column type(s) found: RESUME
ORA-06512: 在 "SYS.DBMS_ERRLOG", line 233
ORA-06512: 在 line 1
可以看到,由于T表拥有不支持的列,导致创建错误记录表的过程报错,错误提示就是T表中包含了不支持的列。
如果手工添加CLOB字段到错误记录表:
SQL> ALTER TABLE T DROP (RESUME);
表已更改。
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG('T', 'T_ERROR_LOG')
PL/SQL 过程已成功完成。
SQL> ALTER TABLE T ADD RESUME CLOB;
表已更改。
SQL> ALTER TABLE T_ERROR_LOG ADD RESUME CLOB;
表已更改。
下面创始执行DML语句:
SQL> INSERT INTO T VALUES (1, LPAD('A', 31, 'A'), 'TEST')
2 LOG ERRORS INTO T_ERROR_LOG
3 REJECT LIMIT 1;
LOG ERRORS INTO T_ERROR_LOG
*第 2行出现错误:
ORA-38904: LOB 列 "RESUME" 不支持 DML错误事件记录
SQL> INSERT INTO T VALUES (1, 'A', 'TEST')
2 LOG ERRORS INTO T_ERROR_LOG
3 REJECT LIMIT 1;
LOG ERRORS INTO T_ERROR_LOG
*第 2行出现错误:
ORA-38904: LOB 列 "RESUME" 不支持 DML错误事件记录
可以看到,Oracle会直接报错。而且第二个INSERT语句的执行也会报错,说明Oracle是在执行之前检查了错误记录表的数据类型,而不是在执行的时候才去处理。
即使Oracle的DML并不包含不支持列的数据,Oracle也会报错:
SQL> INSERT INTO T VALUES (1, 'A', 'TEST');
已创建 1行。
SQL> UPDATE T SET NAME = 'B'
2 WHERE ID = 1
3 LOG ERRORS INTO T_ERROR_LOG
4 REJECT LIMIT 1;
LOG ERRORS INTO T_ERROR_LOG
*第 3行出现错误:
ORA-38904: LOB 列 "RESUME" 不支持 DML错误事件记录
下面创始删除T_ERROR_LOG表中的RESUME列:
SQL> ALTER TABLE T_ERROR_LOG DROP (RESUME);
表已更改。
SQL> UPDATE T SET NAME = 'B'
2 WHERE ID = 1
3 LOG ERRORS INTO T_ERROR_LOG
4 REJECT LIMIT 1;
已更新 1行。
SQL> UPDATE T SET NAME = LPAD('A', 31, 'A')
2 WHERE ID = 1
3 LOG ERRORS INTO T_ERROR_LOG
4 REJECT LIMIT 1;
已更新0行。
SQL> INSERT INTO T VALUES (1, LPAD('A', 31, 'A'), 'TEST')
2 LOG ERRORS INTO T_ERROR_LOG
3 REJECT LIMIT 1;
已创建0行。
SQL> SELECT COUNT(*) FROM T_ERROR_LOG;
COUNT(*)
----------
2
可以看到,删除错误记录语句所不支持的列后,LOG ERRORS语句反而可以顺利执行,而且无论DML语句是否包括哪些不支持列的数据。
不过,对于一个已经在使用的表,是不可能为了添加错误记录表而删除不支持的列,而后在添加回来的,这没有关系,完全可以通过其他表中间表来实现:
SQL> DROP TABLE T_ERROR_LOG PURGE;
表已删除。
SQL> CREATE TABLE T_INTER AS SELECT ID, NAME FROM T;
表已创建。
SQL> EXEC DBMS_ERRLOG.CREATE_ERROR_LOG('T_INTER', 'T_ERROR_LOG')
PL/SQL 过程已成功完成。
SQL> INSERT INTO T VALUES (1, LPAD('A', 31, 'A'), 'TEST')
2 LOG ERRORS INTO T_ERROR_LOG
3 REJECT LIMIT 1;
已创建0行。
可以看到,虽然CREATE_ERROR_LOG过程在创建T_ERROR_LOG表时指定的是T_INTER表,但是这个过程实际上只是根据源表来获取列的信息,而并没有在源表和错误记录表之间建立任何的关系,所以只要列满足条件,任何途径创建的错误记录表都可以使用。
错误记录表还可以手工创建:
SQL> CREATE TABLE T_ERROR_LOG1 AS SELECT * FROM T_ERROR_LOG
2 WHERE 1 = 0;
表已创建。
SQL> DROP TABLE T_ERROR_LOG PURGE;
表已删除。
SQL> INSERT INTO T VALUES (1, LPAD('A', 31, 'A'), 'TEST')
2 LOG ERRORS INTO T_ERROR_LOG1
3 REJECT LIMIT 1;
已创建0行。
- Oracle10g新特性——记录DML错误日志(三)
- Oracle10g新特性——记录DML错误日志
- Oracle10g新特性——记录DML错误日志(一)
- Oracle10g新特性——记录DML错误日志(二)
- Oracle10g新特性——记录DML错误日志(一)
- DBMS_ERRLOG记录DML错误日志(一)
- DBMS_ERRLOG记录DML错误日志(二)
- oracle10g新特性——物化视图
- Oracle10g新特性——正则表达式
- Oracle10g新特性—表空间管理
- DML过程中记录错误日志
- ORACLE10g新特性——全局HASH分区索引
- Oracle10g新特性——利用RMAN迁移表空间
- ORACLE10g新特性——全局HASH分区索引
- oracle10g新特性--回收站
- oracle实现对表dml错误记录日志
- oracle10g/11g 新特性三(Flashback Table)
- oracle DML错误日志
- 新交规,苦了!看后完全懂了新交规
- html5学习资源
- windown XP 下ubuntu 12.04 使用wubi 硬盘安装失败与成功实例1
- FPGA基础之异步复位和同步释放电路的详细解释
- putty 多标签式浏览
- Oracle10g新特性——记录DML错误日志(三)
- day3 extra
- 堆和栈的区别——经典解释
- Oracle 多表更新
- 点击按钮弹出 蒙板 操作页面
- asp.net mvc3总结
- ffmpeg源码获取源地址
- 应该知道的Linux技巧
- 中断服务程序中disable_irq会导致中断死机