Oracle:带有日期列的复合唯一键

Oracle: Composite unique key with Date column

我创建了一个 table 复合唯一键如下--

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: unique constraint (CDUREFDB.TEST11_IDX) violated

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 列 (CC) 上有分区。

更新:

在此 table 中,我们在 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

A date 总是有一个时间部分,所以你的两行有不同的 cc 值。您可以根据 trunc(cc) 值创建一个基于函数的索引,这会将时间组件设置为午夜。

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

当然,这意味着如果您希望查询使用索引,您需要确保您的谓词在 trunc(cc) 而不是 cc.