2009-09-03 9 views
21

Ich versuche, eine eindeutige Einschränkung für zwei Felder in einer Tabelle zu erstellen. Es besteht jedoch eine hohe Wahrscheinlichkeit, dass eine Null ist. Ich fordere nur, dass sie eindeutig sind, wenn beide nicht null sind (name wird niemals null sein).Wie kann ich einen eindeutigen Index in Oracle erstellen, aber Nullen ignorieren?

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

Ignorieren Sie die Semantik der Tabellen- und Feldnamen und ob das Sinn macht - ich einige gerade aus.

Gibt es eine Möglichkeit, eine eindeutige Integritätsbedingung für diese Felder zu erstellen, die die Eindeutigkeit für zwei Werte ungleich null erzwingt, aber ignoriert, wenn mehrere Einträge name nicht null sind und email null ist?

Diese Frage ist für SQL Server, und ich hoffe, dass die Antwort ist nicht das Gleiche: How do I create a unique constraint that also allows nulls?

Antwort

33

Wir dies mit einem funktionsbasierten Index tun können. Im Folgenden wird NVL2() verwendet, das, wie Sie wissen, einen Wert zurückgibt, wenn der Ausdruck nicht null ist, und ein anderer Wert, wenn es null ist. Sie könnten stattdessen CASE() verwenden.

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> 

bearbeiten

Da in Ihrem Szenario Name wird immer aufgefüllt werden Sie nur einen Index wie diese benötigen:

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

Index created. 

SQL> 
+0

+1, FBI, um die Rettung ;-) – DCookie

+0

Dank Mann, großes Lob an Sie! –