我试图在表中的两个字段上创建一个唯一约束.但是,很可能一个人将为空.如果两者都不为null(name
永远不会为null),我只要求它们是唯一的.
create unique index "name_and_email" on user(name, email);
Run Code Online (Sandbox Code Playgroud)
忽略表和字段名称的语义以及这是否有意义 - 我只是做了一些.
有没有办法在这些字段上创建一个唯一约束,它将强制两个非空值的唯一性,但如果有多个条目name
不为null并且email
为null ,则忽略它?
这个问题适用于SQL Server,我希望答案不一样: 如何创建一个也允许空值的唯一约束?
APC*_*APC 34
我们可以使用基于函数的索引来完成此操作.如下NVL2()
所述,如果表达式不为null,则返回一个值,如果为null,则返回不同的值.你可以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>
Run Code Online (Sandbox Code Playgroud)
编辑
因为在您的方案名称中将始终填充您只需要这样的索引:
SQL> create unique index blah_uidx on blah
2 (nvl2(email, name, null), email)
3 /
Index created.
SQL>
Run Code Online (Sandbox Code Playgroud)