代码改变世界

转:oracle10g新功能,log error的实验

2010-04-15 15:35  Tracy.  阅读(1534)  评论(0编辑  收藏  举报

 

oracle10g新功能,log error的实验

当你通过DML语句对一个表进行DML操作时,如果一个违反某种约束的错误记录发生,则整个事务会中止并回滚,
这样会严重影响数据的刷新和浪费系统的性能,为了解决这种问题,oracle10g提供了一个错误记录日志表的功能,
insert操作举例,得用该功能可以将一个源记录集合中满足约束条件的记录插入目的表中,而将违反约束的记录
插入错误日志表,这样既充分利用了系统的资源,又可以延迟处理错误记录.对于数据仓库是一个非常有用的方法.

具体使用该方法一般包括三个步骤:
1
创建错误日志表,共有二种方法
  
法一:DBMS_ERRLOG.create_error_log函数;
  EXEC DBMS_ERRLOG.create_error_log(dml_table_name => 'A')
  
创建出来错误日志表名为err$_a,即创建的error表以err$_开头,加上表名,我们也可指定错误日志表名
  DBMS_ERRLOG.create_error_log(dml_table_name => 'A',err_log_table_name => 'A_LOG');
  
法二:手工创建错误日志表
  
但需要注意的是手工创建的错误日志表结构需要满足oracle规定,否则会报错.
2
执行带 error logging参数的DML语句,insert语法结构如下其实我也没有找到update或者delete相关语法^_^)
        insert_into_clause
        { values_clause [ returning_claus
e ]
        | subquery
        }
        [ error_logging_clause ]
3
查询错误日志表,和一般的select语句一样.

下边我拿insert操作做测试用例

--
创建测试表
CREATE TABLE a
AS
SELECT        ROWNUM id,rownum+1 VALUE
FROM all_objects
WHERE        rownum<3;

--
创建唯一性索引
CREATE UNIQUE INDEX unq_a ON a(id);

--
利用系统包来创建相应error log
EXEC DBMS_ERRLOG.create_error_log(dml_table_name => 'A',err_log_table_name => 'A_LOG');
PL/SQL procedure successfully completed.

SQL> desc A_LOG
Name                  Null?    Type
--------------------- -------- -----------
------
ORA_ERR_NUMBER$                NUMBER         --
错误记录数
ORA_ERR_MESG$                  VARCHAR2(2000) --
错误信息
ORA_ERR_ROWID$                 ROWID          --
错误记录的rowid(仅对updatedelete)
ORA_ERR_OPTYP$                 VARCHAR2(2)    --
操作类型(I-INSERT,U-UPDATE,D-DELETE)
ORA_ERR_TAG$                   VARCHAR2(2000) --
自定义标志说明
ID                             VARCHAR2(4000) --
原表字段
VALUE                          VARCHAR2(4000) --
原表字段
其中前五个字段是固定的,后边字段根据原表确定.


请注意:原表和对应error log表的字段类型是不完全匹配的,其转换规则如下:
NUMBER       
                VARCHAR2(4000)
CHAR/VARCHAR2(n)        VARCHAR2(4000)
NCHAR/NVARCHAR2(n)        NVARCHAR2(4000)
DATE/TIMESTAMP                VARCHAR2(4000)
RAW                        RAW(2000)
ROWID                        UROWID
LONG/LOB               
不支持
自定义类型                不支持

--
插入数据,rownum<3的记录违反约束,ROWNUM=3的记录正常插入
SQL> INSERT     INTO a
  2  SELECT     ROWNUM id, rownum+1 VALUE
  3  FROM       all_objects
  4  WHERE      rownum<4
  5  LOG ERRORS INTO A_LOG REJECT LIMIT UNLIMITED
  6  ;
1 ROWS creat
ed.

--
请注意:此处为UNLIMITED,即不限制错误记录的条数,默认为0,即有错误记录就停止整个事务并回滚,我们也可人为设置一个数目,
--
假设为20,即插入时错误记录数超过20则停止整个事务并回滚~



SQL> select * from A_LOG;
              1
ORA-00001: unique constraint (ETL.UNQ_A) violated

I

1
2

              1
ORA-00001: unique constraint (E
TL.UNQ_A) violated

I


2
3

SQL> select * from A;
         1          2
         2          3
         3          4

--
插入数据,rownum<4的记录违反约束,ROWNUM=4的记录正常插入
SQL> INSERT     INTO a
  2  SELECT     ROWNUM id, rownum+1 VALUE
  3  FROM       all_objects
  4  W
HERE      rownum<5
                          --
加入flag参数
  5  LOG ERRORS INTO A_LOG('test_unique') REJECT LIMIT UNLIMITED
  6  ;
1 row created.
正常插入一行,不报错



SQL> select * from A_LOG;

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated

I

1
2

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated

I


2
3

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated

I
test_unique
1
2

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated


I
test_unique
2
3

    
         1
ORA-00001: unique constraint (ETL.UNQ_A) violated

I
test_unique
3
4

--
手工创建error log,表结构必须一致
DROP TABLE a_log;
CREATE TABLE a_log(
        ORA_ERR_NUMBER$                NUMBER         ,
        ORA_ERR_MESG$                  VARCHAR2(2000) ,
 
      ORA_ERR_ROWID$                 ROWID          ,
        ORA_ERR_OPTYP$                 VARCHAR2(2)    ,
        ORA_ERR_TAG$                   VARCHAR2(2000) ,
        ID                             NUMBER         ,
        VALUE                   
      NUMBER
        );

--
插入违反唯一性约束的记录
SQL> INSERT     INTO a
  2  SELECT     ROWNUM id, rownum+1 VALUE
  3  FROM       all_objects
  4  WHERE      rownum<5
  5  LOG ERRORS INTO A_LOG('test_unique') REJECT LIMIT UNLIMITED
  6  ;

0 rows created.
注意:没有报错


--
查询error log表里边的记录
SQL> select * from A_LOG
  2  /

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated
                   I
test_unique
         1          2

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated
             
     I
test_unique
         2          3

              1

ORA-00001: unique constraint (ETL.UNQ_A) violated
                   I
test_unique
         3          4

              1
ORA-00001: unique constraint (ETL.UNQ_A) violated
                   I
t
est_unique
         4         
5