2009-09-03 8 views
21

Próbuję utworzyć unikalne ograniczenie na dwóch polach w tabeli. Istnieje jednak duże prawdopodobieństwo, że jedna będzie zerowa. Wymagam tylko, aby były one unikalne, jeśli oba nie są zerowe (name nigdy nie będzie mieć wartości NULL).Jak utworzyć unikatowy indeks w Oracle, ale ignorować wartości null?

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

Zignoruj ​​semantykę nazw tabel i pól i czy ma to sens - po prostu wymyśliłem trochę.

Czy istnieje sposób utworzenia unikalnego ograniczenia na tych polach, które wymusi jednoznaczność dla dwóch wartości pustych, ale zignorować, jeśli istnieje wiele pozycji, w których name ma wartość zerową, a email ma wartość null?

To pytanie jest dla SQL Server, a mam nadzieję, że odpowiedź nie jest taka sama: How do I create a unique constraint that also allows nulls?

Odpowiedz

33

Możemy to zrobić za pomocą funkcji indeksu opartego na. Następujące używa NVL2(), które, jak wiadomo, zwraca jedną wartość, jeśli wyrażenie nie ma wartości null i inną wartość, jeśli ma wartość null. Zamiast tego możesz użyć 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> 

Edit

Ponieważ w nazwie scenariusz zawsze będzie wypełniana trzeba tylko indeks takiego:

SQL> create unique index blah_uidx on blah 
    2  (nvl2(email, name, null), email) 
    3/

Index created. 

SQL> 
+0

+1, FBI na ratunek ;-) Dzięki – DCookie

+0

człowiek, skarbie! –