我想创建一个表中的两个字段的唯一约束。 然而,有一个高的可能性,一会是空的。 我只要求他们是唯一的如果两者都没有空( name
永远不会为空)。
create unique index "name_and_email" on user(name, email);
忽略表和字段名的语义是否有意义 - 我只是做了一些了。
有没有一种方法来创建这些领域,将强制唯一两个没有空值的唯一约束,而忽略如果有多个条目,其中name
是不是null, email
为空?
这个问题是SQL Server,和我希望答案是不一样的: 如何创建一个唯一约束也允许空值?
我们可以用一个基于函数的索引做到这一点。 下面利用了NVL2()
正如你知道的,返回一个值,如果表达式不为空和不同的值,如果它是空的。 你可以使用CASE()
来代替。
SQL> create table blah (name varchar2(10), email varchar2(20))
2 /
Table created.
SQL> create unique index blah_uidx on blah
2 (nvl2(email, name, null), nvl2(name, email, null))
3 /
Index created.
SQL> insert into blah values ('APC', null)
2 /
1 row created.
SQL> insert into blah values ('APC', null)
2 /
1 row created.
SQL> insert into blah values (null, 'apc@example.com')
2 /
1 row created.
SQL> insert into blah values (null, 'apc@example.com')
2 /
1 row created.
SQL> insert into blah values ('APC', 'apc@example.com')
2 /
1 row created.
SQL> insert into blah values ('APC', 'apc@example.com')
2 /
insert into blah values ('APC', 'apc@example.com')
*
ERROR at line 1:
ORA-00001: unique constraint (APC.BLAH_UIDX) violated
SQL>
编辑
因为在你的方案名称将永远被组装你只需要一个这样的指标:
SQL> create unique index blah_uidx on blah
2 (nvl2(email, name, null), email)
3 /
Index created.
SQL>
我不知道有多少人仍然可以针对这个答案,但至少在Oracle的最新版本,你可以拥有一个独特的指数与空多行和接受的答案是没有必要的