Domanda

Ho una tabella di database Oracle su cui voglio applicare un vincolo univoco. Il problema è che voglio applicare il vincolo solo se una colonna in quella tabella è nulla,

es. se una riga non ha una colonna delete_date, applica il vincolo, altrimenti ignoralo. Ciò consentirà di eliminare softmente i record e ignorare i vincoli su di essi.

Qualche idea su come farlo?

Saluti, Mark

È stato utile?

Soluzione

Crea semplicemente un vincolo multi colonna: la colonna che vuoi essere unica più la data di eliminazione. Tutte le righe non eliminate avranno un valore univoco e la data di eliminazione sarà nulla. Tutte le righe eliminate saranno uniche a causa della data di eliminazione (supponendo che sia un timestamp e la risoluzione sia abbastanza buona da separare tutte le eliminazioni). Se le righe eliminate non possono essere separate dalla data di eliminazione, si potrebbe pensare di creare una nuova colonna e di aggiungerla al vincolo per unificare la data di eliminazione, ma questa sarebbe una soluzione piuttosto inelegante.

Altri suggerimenti

E se la risoluzione non è abbastanza buona, puoi creare un indice univoco basato sulle funzioni.

Un esempio:

SQL> create table t (id,col,deleted_date)
  2  as
  3  select 1, 99, null from dual union all
  4  select 2, 99, date '2009-06-22' from dual
  5  /

Tabel is aangemaakt.

SQL> alter table t add constraint t_pk primary key (id)
  2  /

Tabel is gewijzigd.

SQL> alter table t add constraint t_uk1 unique (col,deleted_date)
  2  /

Tabel is gewijzigd.

Questa è la soluzione descritta da Daniel. Se c'è mai la possibilità che due righe vengano eliminate contemporaneamente (sto usando solo la parte della data qui), questa soluzione non è abbastanza buona:

SQL> insert into t values (3, 99, date '2009-06-22')
  2  /
insert into t values (3, 99, date '2009-06-22')
*
FOUT in regel 1:
.ORA-00001: unique constraint (RWK.T_UK1) violated

In tal caso, utilizzare un indice univoco basato sulle funzioni:

SQL> alter table t drop constraint t_uk1
  2  /

Tabel is gewijzigd.

SQL> create unique index i1 on t (nvl2(deleted_date,null,col))
  2  /

Index is aangemaakt.

SQL> insert into t values (3, 99, date '2009-06-22')
  2  /

1 rij is aangemaakt.

Saluti, Rob.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top