2016-03-17 51 views
0

我創建了一個表,複合唯一鍵的below--甲骨文:與日柱複合唯一鍵

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值到秒? 因爲我可以看到下面的查詢返回的是result--

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)上有分區。

UPDATE:

在這個表中,我們對DATE列(CC)RANGE分區。

我們計劃定期刪除分區(即過了些日子間隔)。因此,如果我不使用獨特索引中的直接CC(而不是像賈斯汀建議的那樣製作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

一個date總是有一個時間組件,以便您的兩行有不同的cc值。你可以創建基於trunc(cc)值將時間部分設置爲午夜基於函數的索引。

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

當然,這意味着,如果你想查詢使用索引,你會想,以確保您的謂詞是trunc(cc)而非cc

+0

感謝@Justin。那麼在該列上進行分區沒有影響?因爲我們將根據'range partition'定期從這個表中刪除數據,我們將在DATE列上施加這個數據。 –

+1

@AshishPatil - 我一般不會瘋狂的分區表上有全局索引,但你必須與任何索引最初創建或基於函數的索引。我希望在分區被刪除之後或者需要重建。現在,如果你的實際指數是一個本地指數(我認爲這需要'cc'成爲主要專欄),那麼你就有一個完全不同的問題。在這種情況下,在'trunc(cc)'上添加一個虛擬列並根據它進行分區可能是有意義的。 –

+0

再次感謝@JustinCave。我做了DATE列作爲虛擬現在能夠刪除分區,以及我能確保的唯一鍵的成分只使用日期爲成員。 –