带where子句的Oracle唯一约束

时间:2009-06-21 23:44:32

标签: oracle constraints

我有一个Oracle数据库表,我想对其应用唯一约束。问题是我只想在该表中的列为空时应用约束,

即。如果某行没有deleted_date列,则应用约束,否则忽略它。这将允许软删除记录并忽略对它们的约束。

关于如何做到这一点的任何想法?

干杯, 标记

2 个答案:

答案 0 :(得分:6)

只需创建一个多列约束 - 您想要唯一的列加上删除日期。所有未删除的行都将具有唯一值,删除日期为null。由于删除日期,所有删除的行都是唯一的(假设它是一个时间戳,并且分辨率足以分隔所有删除)。如果删除的行不能被删除日期分开,可以考虑创建一个新列并将其添加到约束中以统一删除日期 - 但这将是一个非常不优雅的解决方案。

答案 1 :(得分: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.

此致 罗布。