客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?

oraclebulkcopy:https://docs.oracle.com/html/E10927_01/OracleBulkCopyClass.htm#CHDHHABB

1、问题

客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?
事情的起因是客户遇到ORA-02291外键问题,外键更新列没有找到主表中的列值,由业务去排查,但是通过这个问题进一步发现了业务的重复数据的潜在问题,
及时调整避免长期运行造成更大的问题。
报错如下:
ORA-02291: integrity constraint (ERP_CC.T_ECHDA_T_EZBQGDA_FK1) violated - parent key not found
ORA-06512: at "ERP_CC.UPDATET_ECHDABYT_TMH_PROC", line 346
ORA-06512: at line 1
检查该表的DDL,截取问题部分如下,发现唯一键unusable,一个外键disable,但不是ORA-02291对应的外键,
客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?

进一步排查,发现唯一键YBH28 包含3307条重复数据,这是怎么产生的呢?唯一索引状态还是unusable的。

2、排查

从客户近期的业务调整得知,业务新改动了加载数据的方法,使用了oraclebulkcopy的方式加载数据,insert语句出现 /+ SYS_DL_CURSOR / hint,
该hint就是SQL Loader的方式, 相当于sqlldr(direct=true)直接路径加载,会导致索引失效,因此Bulkcopy需要谨慎使用,要性能的时候要考虑重复数据如何避免。
客户的一张表中出现重复数据,而该列由唯一键约束,重复值如何产生的呢?

3、解决

问题根源找到了,修改加载数据的方法,同时业务去处理重复数据,重新加一下唯一键,失效的外键启用,外键插入引起的ORA-02291问题业务上去检查避免。

4、总结

oraclebulkcopy对应的实现是sqlloader加载数据,有如下限制:
1、会disbale索引
2、direct=true模式加载数据,表的约束会在过程中失效
3、对表加排它锁。

SQL*Loader leaves indexes in an Index Unusable state when the data segment being loaded becomes more up-to-date than the index segments that index it.
Any SQL statement that tries to use an index that is in an Index Unusable state returns an error. The following conditions cause a direct path load to leave an index or a partition of a partitioned index in an Index Unusable state:

* SQL*Loader runs out of space for the index and cannot update the index.
* The data is not in the order specified by the SORTED INDEXES clause.
* There is an instance failure, or the Oracle shadow process fails while building the index.
* There are duplicate keys in a unique index.
* Data savepoints are being used, and the load fails or is terminated by a keyboard interrupt after a data savepoint occurred.

参考文档:
https://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_modes.htm#i1010480

上一篇:使用Oracle logminer 找回delete的数据


下一篇:网友提问:关于CX_VSI_SYSTEM_ERROR异常,Fiori病毒扫描参数文件