A Oracle restrição exclusiva com cláusula where
-
06-07-2019 - |
Pergunta
Eu tenho uma tabela de banco de dados Oracle que eu quero aplicar uma restrição exclusiva em. A questão é que eu só quero aplicar a restrição se uma coluna na tabela é nulo,
ie. Se uma linha não tem uma coluna deleted_date, em seguida, aplicar a restrição, caso contrário, ignorá-lo. Isto irá permitir a exclusão de registros suaves e restrições ignorando sobre eles.
Quaisquer pensamentos sobre como fazer isso?
Cheers, Mark
Solução
Basta criar uma restrição de coluna de multi - coluna você quiser ser original mais a data de eliminação. Todas as linhas não excluídos terá um valor único e o nulo data de exclusão. Todas as linhas excluídas será único por causa da data de eliminação (assumindo que é um carimbo de tempo e a resolução é boa o suficiente para separar todas as exclusões). Se linhas excluídas não podem ser separados pela data de exclusão, pode-se pensar em criar uma nova coluna e adicioná-lo ao constrangimento para uniquify a data de eliminação -. Mas isso seria uma solução bastante deselegante
Outras dicas
E se a resolução não é bom o suficiente, então você pode criar um índice baseado em função único.
Um exemplo:
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.
Esta é a solução descrita por Daniel. Se há sempre uma possibilidade de que duas linhas são excluídas no exato mesmo tempo (estou usando apenas a parte data aqui), esta solução não é bom o suficiente:
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
Nesse caso, use um índice baseado em função única:
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.
Saudações, Rob.