非唯一索引可以避免记录重复

时间:2018-09-13 10:50:00

标签: sql oracle

我有一个无法创建主键和唯一索引的表,原因是该表包含员工的薪水数据,员工代码是唯一的,但是由于薪水代码不同并且每个薪水代码与单个员工相关联,这就是为什么我们允许记录的重复。

现在的问题是,工资数据被第三方供应商推送到共享数据库中,当我们将薪水数据迁移到数据库中时,发生了数据记录插入两次或三次的情况。

例如,假设第三方推送了5000条记录,现在我们需要将这5000条记录提取到数据库中,但是上个月发生了3到4次数据提取,它变成了20,000条记录而不是5000条记录,原因很简单我们的表中没有任何验证。

现在建议我创建唯一索引以避免重复,但是由于重复了员工代码,所以我无法做到这一点。

现在我们只剩下非唯一索引了,我听不懂,这真的对避免重复很有帮助。

我的主要目的是避免重复。 请建议我更好的解决方案。

这是一些数据

   SALARY_REPORT_ID EMP_NAME    EMP_CODE    PAY_CODE    PAY_CODE_NAME   AMOUNT  PAY_MODE    PAY_CODE_DESC   YYYYMM  REMARK  EMP_ID  PRAN_NUMBER PF_NUMBER   PRAN_NO ATTOFF_EMPCODE  REFERENCE_ID
    13488158    Mr. Javed Jafri 91559037    104     7427    1   HOUSE RENT ALLOW    201802      119     22782303        150025  1-268
    13488159    Mr. Javed Jafri 91559037    100     23885   3   BASIC PAY   201802      119     22782303        150025  1-268
    13488160    Mr. Javed Jafri 91559037    103     9590    1   DEARNESS ALLOW. 201802      119     22782303        150025  1-268
    13488161    Mr. Javed Jafri 91559037    100     191800  1   BASIC PAY   201802      119     22782303        150025  1-268
    13488162    Mr. Javed Jafri 91559037    303     40000   2   PF SUB-PAY(GPF) 201802      119     22782303        150025  1-268
    13488163    Mr. Javed Jafri 91559037    502     20  2   G.T.I.S.    201802      119     22782303        150025  1-268
    13488164    Mr. Javed Jafri 91559037    503     72  2   SCLIS   201802      119     22782303        150025  1-268
    13488165    Mr. Javed Jafri 91559037    999     69441   1   NET EARNING 201802      119     22782303        150025  1-268
    13488166    Mr. Javed Jafri 91559037    998     195692  2   GROSS DEDUCTION 201802      119     22782303        150025  1-268
    13488167    Mr. Javed Jafri 91559037    997     265133  1   GROSS EARNING   201802      119     22782303        150025  1-268
    13488168    Mr. Javed Jafri 91559037    134     16006   3   WAGE REVISION ARREARS   201802      119     22782303        150025  1-268
    13488169    Mr. Javed Jafri 91559037    108     400 1   CONVEYANCE ALLOWANCE    201802      119     22782303        150025  1-268
    13488170    Mr. Javed Jafri 91559037    134     16025   3   WAGE REVISION ARREARS   201802      119     22782303        150025  1-268
    13488171    Mr. Javed Jafri 91559037    506     600 2   GSLI(Board Employee)    201802      119     22782303        150025  1-268
    13488172    Mr. Javed Jafri 91559037    312     155000  2   INCOME TAX  201802      119     22782303        150025  1-268

更多缩进方式 enter image description here

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么您应该在(employee_id,pay_code)上创建多列唯一索引。您必须找到应该唯一的列的组合,并基于该列创建索引。

答案 1 :(得分:0)

您似乎想要的唯一约束是对your_table(EMP_CODE,PAY_CODE)的复合约束;

只有当该列组合的值重复时,您才能创建该约束。因此,您需要清理数据。幸运的是,Oracle可以在此练习中为您提供支持。

首先,您需要创建一个例外报告表(如果您还没有的话)。 Oracle为此表定义了标准结构,因此您(或您的友好DBA)应运行以下脚本:@$ORACLE_HOME/rdbms/admin/utlexcpt.sql

然后创建约束:

alter table your_table 
    add constraint your_table_uk unique (EMP_CODE,PAY_CODE)
    exceptions into EXCEPTIONS;  -- or whatever you called your reporting

这将失败,但是它将为所有违例行的ROWID填充EXCEPTIONS表。现在,您可以浏览表格并删除所有重复的行。

如果您认为这可能需要很长时间,或者-如果确实如此-您不想清理重复项,则应使用NOVALIDATE选项。这样至少可以防止情况恶化。为此,您需要在添加约束之前在(EMP_CODE,PAY_CODE)上创建一个非唯一索引。当您添加唯一约束时,Oracle将使用现有索引来强制执行它,而不会出现任何问题。但是我们不能将NOVALIDATE选项与唯一索引一起使用。 Find out more

但是请确保您确实能够清理重复项!