Quantcast
Channel: Mohamed Houri’s Oracle Notes
Viewing all articles
Browse latest Browse all 224

On how to enforce uniqueness when unique constraint is not possible

$
0
0

The following select gives a list of existing table that do not possess a unique constraint

select table_name
from user_tables u1
where not exists (select null
from  user_constraints u2
where u2.table_name      = u1.table_name
and   u2.constraint_type = 'U');

However, the above select doesn’t mean that there isn’t any other uniqueness enforcement  implemented without a dedicated unique constraint.

Recently, I have been confronted to a business rule to be implemented in a Data Vault model which specifies that each Satellite or Satellite of Link table should have a unique key enforcement satisfying the following rule

For each couple of (col1, col2) I could have at most a unique record for a not null dv_load_end_date column.

A picture being worth a thousand words let’s see this through a real example


SQL> create table t1
(t1_sk            number
,dv_load_date     date
,seq_nbr          number
,n1               number
,n2               number
,status           varchar2(10)
,identification   varchar2(30)
,dv_load_end_date date);

SQL> alter table t1 add constraint t1_pk primary key (t1_sk,dv_load_date, seq_nbr);

The unique business rule would be described as follows: for each couple (t1_sk, n2) I could have at most one record for a null dv_load_end_date column

Is this doable via a unique constraint? No it is not.

And here where function based index comes to the rescue

SQL> create unique index ind_t1_uk on t1
(case when dv_load_end_date is null then t1_sk else null end
,case when dv_load_end_date is null then n2 else null end);

And here how the inserts go

SQL> insert into t1 (t1_sk ,dv_load_date ,seq_nbr,n1,n2,dv_load_end_date)
              values(1, sysdate, 1, 1, 100, null);

1 row created.

SQL> insert into t1 (t1_sk ,dv_load_date ,seq_nbr,n1,n2,dv_load_end_date)
              values(1, sysdate, 1, 1, 100, sysdate);

1 row created.

SQL> insert into t1 (t1_sk ,dv_load_date ,seq_nbr,n1,n2,dv_load_end_date)
              values(1, sysdate, 1, 1, 100, null);

insert into t1 (t1_sk ,dv_load_date ,seq_nbr,n1,n2,dv_load_end_date)
*
ERROR at line 1:
ORA-00001: unique constraint (XXX.IND_T1_UK) violated

SQL> insert into t1 (t1_sk ,dv_load_date ,seq_nbr,n1,n2,dv_load_end_date)
              values(1, sysdate, 1, 1, 200, null);
1 row created.

This post is the second one in a set of small scripts (blog articles) I decided to collect in my blog for my documentation and reuse purposes



Viewing all articles
Browse latest Browse all 224

Latest Images

Trending Articles



Latest Images