условное уникальное ограничение на несколько столбцов в Oracle - PullRequest
1 голос
/ 19 июня 2019

У меня есть таблица с тремя столбцами - c_id, o_id, f_id.Комбинация трех идентификаторов должна быть уникальной, если f_id не равен 3.

После прочтения похожих вопросов я попробовал следующее:

create unique index my_index on my_table (
decode (f_id, !3, c_id, null),
decode (f_id, !3, o_id, null),
decode (f_id, !3, f_id, null));

, но я получаю отсутствует выражение ошибка.Я также пробовал с

create unique index my_index on my_table ((
case 
when f_id <> 3 then c_id
when f_id <> 3 then o_id
when f_id <> 3 then f_id
else null
end));

, но для этого я получаю , не могу создать индекс;найдено повторяющихся ключей

Первоначально я пытался

when f_id <> 3 then (c_id, o_id, f_id)

, но это не сработало вообще.

В любом случае, возможно, что-то не так с индексом, посколькуВ таблице, похоже, нет дубликатов, я не получаю записей с

select c_id, o_id, f_id, count(*) as dupes
from my_table
where f_id <> 3
having count(*) > 1
group by c_id, o_id, f_id;

Я вроде как ослеп на этих ФБР, поэтому любая помощь будет признательна.

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Альтернативный подход только с одним индексом столбца:

create unique index all_but_3 on tst (case when nvl(f_id,0) != 3 then o_id||'.'||c_id||'.'||f_id end);

Test

insert into tst(c_id, o_id, f_id) values(3,3,3);
insert into tst(c_id, o_id, f_id) values(3,3,3); -- OK

insert into tst(c_id, o_id, f_id) values(3,3,2);
insert into tst(c_id, o_id, f_id) values(3,3,2); -- ORA-00001: unique constraint  xxx violated

insert into tst(c_id, o_id, f_id) values(3,3,null);
insert into tst(c_id, o_id, f_id) values(3,3,null); -- ORA-00001: unique constraint  xxx violated

insert into tst(c_id, o_id, f_id) values(null,null,2);
insert into tst(c_id, o_id, f_id) values(null,null,2); -- -- ORA-00001: unique constraint  xxx violated
1 голос
/ 19 июня 2019

Вы, кажется, хотите индекс из трех частей:

create unique index my_index
    on my_table (case when f_id <> 3 then c_id end,
                 case when f_id <> 3 then o_id end,
                 case when f_id <> 3 then f_id end
                );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...