Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como posso criar um índice exclusivo no Oracle, mas ignorar nulos?


Podemos fazer isso com um índice baseado em função. O seguinte faz uso de NVL2() que, como você sabe, retorna um valor se a expressão não for nula e um valor diferente se for nula. Você pode usar CASE() em vez de.
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>

Editar

Como no seu cenário o nome sempre será preenchido, você precisará apenas de um índice como este:
SQL> create unique index blah_uidx on blah
  2      (nvl2(email, name, null), email)
  3  /

Index created.

SQL>