Oracle:具有Date列的复合唯一键

时间:2016-03-17 20:34:59

标签: oracle11g unique-constraint

我创建了一个带有复合唯一键的表,如下所示 -

create table test11 
(
     aa number, 
     bb varchar2(10),
     cc DATE, 
     dd number,
     ee NUMBER
);

CREATE UNIQUE INDEX TEST11_IDX ON TEST11 (AA,BB,CC);

现在,每当我尝试插入数据时,都会收到此错误:

  

ORA-00001:违反了唯一约束(CDUREFDB.TEST11_IDX)

INSERT INTO TEST11 VALUES (1, 'AA', SYSDATE, 1, 1);
commit;

INSERT INTO TEST11 VALUES (1, 'AA', SYSDATE, 1, 1);
commit;

这是因为DATE列正在考虑Date值直到秒? 因为我可以看到下面的查询返回结果 -

select to_char(CC,'DD-Mon-YY HH:Mi:SS AM') from test11;

TO_CHAR(CC,'DD-MON-YYHH:MI:SSAM')
---------------------------------
17-Mar-16 04:28:37 PM             
17-Mar-16 04:28:43 PM   

那么,为了只将Date值(不是小时,分钟,秒精度)视为唯一的关​​键成员,可以做些什么。

此外,上面的DATE列(CC)上有分区。

更新:

在此表中,我们在DATE列(CC)上有RANGE分区。

我们计划定期删除分区(即在几天后间隔)。

因此,如果我不在独特索引中使用直接CC(而不是像Justin建议的那样使用trunc),那么如果我尝试在删除某个旧分区后插入数据,则会收到错误ORA-01502: index 'CDUREFDB.TEST111_IDX' or partition of such index is in unusable state

UPDATE_1 根据下面的@Justin建议,此问题已解决,如下所示创建虚拟列:

CREATE TABLE TEST11
  (
    AA NUMBER,
    BB VARCHAR2(10),
    CC DATE,
    DD NUMBER ,
    EE NUMBER,
    FF DATE generated always AS (TRUNC(CC)) virtual
  )
  PARTITION BY RANGE
  (
    FF
  )
  INTERVAL
  (
    NUMTODSINTERVAL(1,'DAY')
  )
  (
    PARTITION partition_test_1 VALUES LESS THAN (TO_DATE('01-APR-2006','dd-MON-yyyy'))
  );



CREATE UNIQUE INDEX TEST111_IDX ON TEST11 (AA,BB,FF) LOCAL;  -- creating unique local index

1 个答案:

答案 0 :(得分:1)

trunc(cc)始终有一个时间组件,因此您的两行具有不同的CREATE UNIQUE INDEX TEST11_IDX ON TEST11 (AA,BB,trunc(CC)); 值。您可以基于trunc(cc)值创建基于函数的索引,该值将时间组件设置为午夜。

cc

当然,这意味着如果您希望查询使用索引,则需要确保谓词位于{{1}}而不是{{1}}。