Oracle – How to Prevent Duplicate Values in Column During Insert

oracle

I have table

TABLE1(
 id number (primary key),
 IDAccount number,
 status char(10))

Table can have 2 row duplicate (IDAccount, status) with status=disable as well as

id     IDAccount     status
1       100          DISABLE
2       100          DISABLE

But, mustn't have 2 row duplicate (IDAccount, status) with status=enable as well as:

id     IDAccount     status
3       200          ENABLE
4       200          ENABLE // DON'T ALLOW

How I can do it ?
Thanks.

Best Answer

This can be done with a partial index. A bit complicated in Oracle because it doesn't allow a where clause in the create index statement (as e.g. Postgres does).

But you can still trick Oracle in only indexing a sub-set of the rows by exploiting the fact that entries where all index columns are null are not put into the index. So you create a a unique index on an expression that is only not-null if the status is 'ENABLE':

create unique index ix_only_one_enabled
  on table1 ( case when status = 'ENABLE' then idaccount else null end);

The expression will yield null for all rows where the status is something else than enable and those rows won't be put into the index. Which in turn means than only the IDACCOUNT values for rows are put into the index where the status is ENABLE

Note that 'enable' and 'ENABLE' are two different values for Oracle. You probably also want a check constraint on your column to make sure you only put uppercase values in there (or use a trigger),


Unrelated but: you most probably do not want to use CHAR(10) but VARCHAR(10) due to the padding that happens when using the dreaded char data type.