我有一個Oracle數據庫表,我想對其應用唯一約束。問題是我只想應用該約束條件,如果該表中的一列爲空,即Oracle對where子句的唯一約束條件
即。如果某行沒有deleted_date列,則應用約束,否則忽略它。這將允許軟刪除記錄並忽略它們的限制。
有關如何做到這一點的任何想法?
乾杯, 馬克
我有一個Oracle數據庫表,我想對其應用唯一約束。問題是我只想應用該約束條件,如果該表中的一列爲空,即Oracle對where子句的唯一約束條件
即。如果某行沒有deleted_date列,則應用約束,否則忽略它。這將允許軟刪除記錄並忽略它們的限制。
有關如何做到這一點的任何想法?
乾杯, 馬克
只需創建一個多列約束 - 你想成爲唯一的列加上刪除日期。所有未被刪除的行將具有唯一值並且刪除日期爲空。由於刪除日期(假定它是時間戳並且分辨率足以分隔所有刪除),所有刪除的行都將是唯一的。如果被刪除的行不能被刪除日期分隔,那麼可以考慮創建一個新列並將其添加到約束來唯一化刪除日期 - 但這是一個相當不雅的解決方案。
如果分辨率不夠好,那麼您可以創建一個獨特的基於函數的索引。
一個例子:
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.
問候, 羅布。
+1:基於獨特功能的索引可能比目前接受的答案更好 – 2012-03-22 12:34:26
男人,我試圖想想這一個!謝謝,那會很好,我認爲 – Mark 2009-06-22 00:15:10