2009-06-21 78 views
2

我有一個Oracle數據庫表,我想對其應用唯一約束。問題是我只想應用該約束條件,如果該表中的一列爲空,即Oracle對where子句的唯一約束條件

即。如果某行沒有deleted_date列,則應用約束,否則忽略它。這將允許軟刪除記錄並忽略它們的限制。

有關如何做到這一點的任何想法?

乾杯, 馬克

回答

6

只需創建一個多列約束 - 你想成爲唯一的列加上刪除日期。所有未被刪除的行將具有唯一值並且刪除日期爲空。由於刪除日期(假定它是時間戳並且分辨率足以分隔所有刪除),所有刪除的行都將是唯一的。如果被刪除的行不能被刪除日期分隔,那麼可以考慮創建一個新列並將其添加到約束來唯一化刪除日期 - 但這是一個相當不雅的解決方案。

+0

男人,我試圖想想這一個!謝謝,那會很好,我認爲 – Mark 2009-06-22 00:15:10

4

如果分辨率不夠好,那麼您可以創建一個獨特的基於函數的索引。

一個例子:

SQL> create table t (id,col,deleted_date) 
    2 as 
    3 select 1, 99, null from dual union all 
    4 select 2, 99, date '2009-06-22' from dual 
    5/

Tabel is aangemaakt. 

SQL> alter table t add constraint t_pk primary key (id) 
    2/

Tabel is gewijzigd. 

SQL> alter table t add constraint t_uk1 unique (col,deleted_date) 
    2/

Tabel is gewijzigd. 

這是由Daniel描述的解決方案。如果有過一種可能性,即兩行的確切也同時被刪除(我只使用日期部分在這裏),該解決方案還不夠好:

SQL> insert into t values (3, 99, date '2009-06-22') 
    2/
insert into t values (3, 99, date '2009-06-22') 
* 
FOUT in regel 1: 
.ORA-00001: unique constraint (RWK.T_UK1) violated 

在這種情況下,使用基於一個獨特的功能指數:

SQL> alter table t drop constraint t_uk1 
    2/

Tabel is gewijzigd. 

SQL> create unique index i1 on t (nvl2(deleted_date,null,col)) 
    2/

Index is aangemaakt. 

SQL> insert into t values (3, 99, date '2009-06-22') 
    2/

1 rij is aangemaakt. 

問候, 羅布。

+0

+1:基於獨特功能的索引可能比目前接受的答案更好 – 2012-03-22 12:34:26