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

Oracle unique index with null and special value allowed

我今天有一个唯一索引,它允许列 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' 上创建索引,这是不允许的。

当有 ssn = 'SPECIAL_VALUE' 时,您必须使用其他列,例如 PK_COLUMN,这样每一行的 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。所以我稍微修改了一下。