ORACLE11GR2 中使用 IGNORE_ROW_ON_DUPKEY_INDEX

我们经常需要把部分在线系统表的数据进行部分备份,例如门诊医生站和门诊收费的中间表outp_orders_costs

创建备份表并 把数据备份过来:

 

时间A 的时候

点击(此处)折叠或打开

  1. create table OUTP_ORDERS_COSTS_BAK as
  2.    select * from OUTP_ORDERS_COSTS ;
  3.  
  4. alter table OUTP_ORDERS_COSTS_BAK
  5.   add constraint PK_OUTP_ORDERS_COSTS_BAK primary key (SERIAL_NO, ORDER_CLASS, ORDER_NO, ITEM_NO);
  6.  
  7. create index IN1_2_OUTP_ORDERS_COSTS_BAK on OUTP_ORDERS_COSTS_BAK (VISIT_DATE, VISIT_NO);



原始表只保留部分数据:

点击(此处)折叠或打开

  1. truncate table OUTP_ORDERS_COSTS ;
  2.  

  3.  insert /*+ append */ into OUTP_ORDERS_COSTS
  4.   select * from OUTP_ORDERS_COSTS_BAK where visit_date < sysdate -1;


 

 

假设系统又运行了很长时间,OUTP_ORDERS_COSTS 又多了很多数据,有需要清理。

 

如果直接insert into  OUTP_ORDERS_COSTS_BAK  因为时间A 中的部分数据在OUTP_ORDERS_COSTS OUTP_ORDERS_COSTS_BAK 都存在,因此可能报错,例如:

点击(此处)折叠或打开

  1. SQL> insert /*+ append*/ into OUTP_ORDERS_COSTS_BAK
  2.   2 select * from OUTP_ORDERS_COSTS ;
  3.    insert /*+ append*/ into OUTP_ORDERS_COSTS_BAK
  4. *
  5. ERROR at line 1:
  6. ORA-00001: unique constraint (HR.PK_OUTP_ORDERS_COSTS_BAK) violated


以前只有写SQL 把这些数据剥离出来, 例如加个where子句,把两个表的交集剃掉。例如:


点击(此处)折叠或打开

  1. into OUTP_ORDERS_COSTS_BAK
  2.      select *
  3.       from OUTP_ORDERS_COSTS
  4.      where (SERIAL_NO, ORDER_CLASS, ORDER_NO, ITEM_NO) not in
  5.            (select SERIAL_NO, ORDER_CLASS, ORDER_NO, ITEM_NO
  6.                from OUTP_ORDERS_COSTS_BAK);


ORACLE11GR2 之后,可以这样:



点击(此处)折叠或打开

  1. insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(OUTP_ORDERS_COSTS_BAK,PK_OUTP_ORDERS_COSTS_BAK)*/
  2.     into OUTP_ORDERS_COSTS_BAK
  3.       select * from OUTP_ORDERS_COSTS ;


  处理起来更简单。

 


IGNORE_ROW_ON_DUPKEY_INDEX  针对的只要是唯一索引即可,不一定要求一定是主键。虽然主键一般会有一个唯一性索引。

 

在使用上可以指定索引名,如上例,也可以指定列名,如下例。


 

点击(此处)折叠或打开

  1. insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(OUTP_ORDERS_COSTS_BAK(SERIAL_NO, ORDER_CLASS, ORDER_NO, ITEM_NO)))*/
  2.       into OUTP_ORDERS_COSTS_BAK
  3.      select * from OUTP_ORDERS_COSTS ;

 

这个提示,是更适合在增量备份中使用。

请使用浏览器的分享功能分享到微信等