Więc co, co ma wymusić regułę gdzie tylko zapis nie może być anulowany dla każdej permutacji LOC_ID, data, godzina? Możemy to zrobić za pomocą unikalnego indeksu opartego na funkcjach.
To właśnie chcemy uniknąć:
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>
Zbudujmy indeks egzekwować rządy
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>
Funkcja NVL2()
jest specjalną formą przypadek, który zwraca drugi argument, jeśli pierwszy argument NIE jest równy NULL, w przeciwnym razie trzeci. Indeks używa PK col jako drugiego argumentu, ponieważ jest kluczem podstawowym, a więc unikalnym. Więc indeks pozwala zduplikowane wartości anulowanych chyba że są nieważne:
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>
swoim przykładzie dane nie dają podstaw do odrzucenia wiersza z PK = 4, gdy nie odrzuca on również z PK = 2. –
@ Jonathan Leffler - Pokonaj mnie. Miałem to samo pytanie. – Thomas
Tak, PK = 2 jest OK. Anulowane może mieć dowolną wartość, ale nie zerową dwukrotność dla tego samego miejsca, daty i godziny. –