では、LOC_ID、DATE、TIMEの特定の順列に対して、レコードのみをキャンセルできないルールを適用するにはどうすればよいでしょうか。これは、関数ベースの一意のインデックスを使用して行うことができます。
これは私たちが避けたいことです:
SQL> select * from t34
2 /
PK LOC_ID SOMEDATE SOMETIM CAN
---------- ---------- ---------- ------- ---
1 1 01/01/2010 10:00AM YES
2 1 01/01/2010 10:00AM YES
3 1 01/01/2010 10:00AM
SQL> insert into t34
2 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null )
3 /
1 row created.
SQL>
ルールを適用するためのインデックスを作成しましょう
SQL> rollback
2 /
Rollback complete.
SQL> create unique index t34_uidx
2 on t34 (loc_id, somedate, some_time, nvl2(cancelled, pk, null) )
3 /
Index created.
SQL>
このNVL2()
関数は、最初の引数がNOT NULLの場合は2番目の引数を返し、それ以外の場合は3番目の引数を返すCASEの特殊な形式です。インデックスはPKcolを2番目の引数として使用します。これは、PK colが主キーであり、したがって一意であるためです。したがって、インデックスは、nullでない限り、CANCELEDの重複値を許可します。
SQL> insert into t34
2 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null )
3 /
insert into t34 values (4 , 1 , to_date('01/01/2010','DD/MM/YYYY') , '10:00AM', null )
*
ERROR at line 1:
ORA-00001: unique constraint (APC.T34_UIDX) violated
SQL>