There is a table with phone numbers:
create table phone ( client_id number(6) not null, active number(1) not null check (active in (0, 1)), value varchar2(15) ); insert into phone (client_id, active, value) values (10, 0, '1111'); insert into phone (client_id, active, value) values (10, 1, '3333'); insert into phone (client_id, active, value) values (15, 0, '5555'); insert into phone (client_id, active, value) values (15, 1, '6666'); insert into phone (client_id, active, value) values (15, 0, '7777'); --ошибочная запись
Tried to ensure only one active phone per client using a unique index but couldn't get it to work.
When I try to create an index:
create unique index ix1 on phone (client_id, case when active = 1 then active end);
I get an error because the index entry is not unique:
Error: ORA-01452: cannot CREATE UNIQUE INDEX; duplicate keys found
But it works fine in PostgreSQL .
Why doesn't it work in Oracle then?
Two inactive records will get
NULL values from the
CASE expression, would they be equal in Oracle? If we delete the last entry with the value 7777, then the index will be created.
create unique index ix1 on phone (case active when 1 then client_id end);
A unique index does not save records only if the values of all columns are
NULL . However, in this case, a function-based index results in one of the two columns being
NULL , so the entry will be indexed, resulting in a duplicate value in the index.
If you change the index so that only one value derived from the
client_id columns is indexed, i.e. so that records where
active = 0 result in a
NULL value from the
CASE expression, then those records will not be included in the index, and only active records will be checked for duplicates.
This is mentioned in sub. Unique Constraints Documentation :
To satisfy a unique constraint, no two rows in the table can have the same value for the unique key. However, the unique key made up of a single column can contain nulls . To satisfy a composite unique key, no two rows in the table or view can have the same combination of values in the key columns. Any row that contains nulls in all key columns automatically satisfies the constraint. However, two rows that contain nulls for one or more key columns and the same combination of values for the other key columns violate the constraint .