允许空值和特殊值的 Oracle 唯一索引

问题描述

我今天有一个唯一索引,它允许列 ssn 的所有空值,但如果它有一个值,它必须与 server 组合是唯一的。

现在我想改变它,使它既允许空值又允许一个特殊定义的值。

旧索引是这样创建的:

CREATE UNIQUE INDEX UQ_SSN ON person (
    CASE WHEN ssn IS NULL THEN NULL ELSE server END,ssn);

现在我想把它改成这样:

CREATE UNIQUE INDEX UQ_SSN ON person (
    CASE WHEN (ssn IS NULL OR ssn = 'SPECIAL_VALUE') THEN NULL ELSE server END,ssn);

虽然那行不通。使用该索引,我仍然可以添加空值。但我只允许添加一行,其中 ssn = 'SPECIAL_VALUE',在第二行我收到错误

ORA-00001:违反了唯一约束 (APP_DB.UQ_SSN)

解决方法

您遇到了这个问题,因为当 ssn = 'SPECIAL_VALUE'null,'SPECIAL_VALUE' 上创建索引时,当您插入新记录时,它也在 null,'SPECIAL_VALUE' 上创建索引,这是不允许的。>

当存在 PK_COLUMN 时,您必须使用其他一些列,例如 ssn = 'SPECIAL_VALUE',这样每行的 null,pk_col 都会不同。

在索引的第二列中尝试 case..when

CREATE UNIQUE INDEX UQ_SSN ON person (
    server,CASE WHEN ssn is null or ssn = 'SPECIAL_VALUE' THEN to_char(id) ELSE ssn END);

注意:您可以在没有 else 的情况下使用 CASE .. WHEN。所以我稍微修改了一下。