【发布时间】:2021-10-06 01:40:29
【问题描述】:
我试图使用 Oracle 中的唯一索引强制每个客户端仅使用一部活动电话,但无法使其正常工作。这在 PostgreSQL 和 DB2 中完美运行,但在 Oracle 中似乎不起作用。
示例如下:
create table phone (
client_id number(6) not null,
active number(1) not null check (active in (0, 1)),
value varchar2(15)
);
insert into phone (client_id, active, value) values (10, 0, '1111');
insert into phone (client_id, active, value) values (10, 1, '3333');
insert into phone (client_id, active, value) values (15, 0, '5555');
insert into phone (client_id, active, value) values (15, 1, '6666');
insert into phone (client_id, active, value) values (15, 0, '7777'); -- offending row
当我尝试创建索引时:
create unique index ix1 on phone (client_id, case when active = 1 then active end);
似乎Oracle不喜欢它,因为重复的索引条目:
错误:ORA-01452:无法创建唯一索引;发现重复键
SQLState: 72000
如果我删除了有问题的数据行,则可以创建索引。
【问题讨论】:
-
您的索引有一个
case,但没有else。当case的结果不是 1 时,Oracle 是否为它分配了 0?似乎当该行不活动时,它将是0,导致两行带有 (15, 0)。你的问题的标题是关于 NULL 的,但我没有看到 NULL 进入方程(?)。 -
我希望
on phone (case when active=1 then client_id end)能够跨数据库引擎工作。我现在没有时间验证并写下答案,但如果没有人超过我,我会在以后尝试这样做。 -
@HardCode - 默认的
else值是null(不仅在Oracle 中,而且我相信在SQL 标准中)。所以从这个角度来看,OP的尝试很好。问题是不同的 - 这是 MT0 在他的回答中解释的。 -
null永远不会等于null。