2009-09-03 108 views
21

我想創建一個表中的兩個字段的唯一約束。但是,很有可能一個將是空的。我只要求它們是唯一的,如果兩者都不爲空(name永遠不會爲空)。如何在Oracle中創建唯一索引但忽略空值?

create unique index "name_and_email" on user(name, email); 

忽略表和字段名稱的語義以及是否有意義 - 我只是做了一些。

有沒有一種方法來創建這些領域,將強制唯一兩個沒有空值的唯一約束,而忽略如果有多個條目,其中name不是null email爲空?

這個問題是SQL Server,和我希望答案是不一樣的: How do I create a unique constraint that also allows nulls?

回答

33

我們可以用一個基於函數的索引做到這一點。如您所知,以下使用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, '[email protected]') 
    2/

1 row created. 

SQL> insert into blah values (null, '[email protected]') 
    2/

1 row created. 

SQL> insert into blah values ('APC', '[email protected]') 
    2/

1 row created. 

SQL> insert into blah values ('APC', '[email protected]') 
    2/
insert into blah values ('APC', '[email protected]') 
* 
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> 
+0

+1,FBI救援;-) – DCookie 2009-09-03 17:25:14

+0

謝謝男人,讚美你! – 2014-08-05 09:14:59