这是我在 Oracle 数据库 (10g) 中运行的一个小实验。除了(Oracle 的)实现方便之外,我无法弄清楚为什么一些插入被接受而另一些被拒绝。
create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);
insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected
insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- rejected
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- rejected
insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted
假设偶尔有一些列值未知的行是有意义的,我可以想到两个可能的涉及防止重复的用例:
1. 我想拒绝重复,但在任何受约束的列的值未知时接受。
2. 我想拒绝重复,即使在约束列的值未知的情况下。
显然,Oracle 实现了一些不同的东西:
3. 拒绝重复,但(仅)在所有受约束的列值都未知时接受。
我可以想办法利用 Oracle 的实现来处理用例 (2)——例如,为“未知”设置一个特殊值,并使列不可为空。但我不知道如何使用用例(1)。
换句话说,我怎样才能让 Oracle 这样做呢?
create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);
insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected
insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- accepted
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted