这是我在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的实现来使用case(2) - 例如,为"unknown"设置一个特殊值,并使列不可为空.但我无法弄清楚如何使用案例(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
DCookie.. 7
尝试基于函数的索引:
在沙箱上创建唯一索引sandbox_idx(例如,当a为空时为空,然后为空,则为空,然后为||','|| b END);
还有其他方法可以给这只猫上皮,但这只是其中之一.
尝试基于函数的索引:
在沙箱上创建唯一索引sandbox_idx(例如,当a为空时为空,然后为空,则为空,然后为||','|| b END);
还有其他方法可以给这只猫上皮,但这只是其中之一.
create unique index sandbox_idx on sandbox (case when a is null or b is null then null else a end, case when a is null or b is null then null else b end);
功能指数!基本上我只需要确保我想忽略的所有元组(即 - 接受)都被转换为所有空值.丑陋,但不是很难看.按需工作.
借助另一个问题的解决方案找出它:如何约束数据库表,以便只有一行可以在列中具有特定值?
所以去那里也给托尼安德鲁斯点.:)