允许具有空值和特殊值的 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
。所以我稍微修改了一下。
我今天有一个唯一索引,它允许列 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
。所以我稍微修改了一下。