这是我在 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