Ограничение Oracle/уникальный индекс: проверьте, не имеет ли запрос результата, - тогда вы можете вставить строку

Я делал что-то подобное в прошлом с целью ограничения диапазона ячеек:

ALTER TABLE "CES"."NS_CES" ADD CONSTRAINT "CHECK_OVER_DIAPAZON" CHECK (
        (ID_NS_WORK != 1835 AND ID_NS_WORK != 1833) OR
        (ID_NS_WORK = 1835 and PNS BETWEEN 0 AND 100 and QNS BETWEEN -200 AND 10) OR
        (ID_NS_WORK = 1833 and PNS BETWEEN 0 AND 100 and QNS BETWEEN -200 AND 10)
    );

Но теперь у меня другая задача: добавить ограничение, которое будет проверять, что результат запроса не возвращает никакого значения.

Это мой выбор, который не должен возвращать значения и который я хочу создать в качестве контрольного ограничения для таблицы Training_rule:

select type, training_list_id, element_id, request_code
from training_rule
where after_rule is null and after_group is null
group by type, training_list_id, element_id, request_code
having count(*) > 1;

Что-то вроде этого:

ALTER TABLE "CES"."TRAINING_RULE" ADD CONSTRAINT "CHEK_SELECT_HAS_NO_RESULT" CHECK (
    ^HAS NO RESULT^:
    [
    select type, training_list_id, element_id, request_code
        from training_rule
        where after_rule is null and after_group is null
        group by type, training_list_id, element_id, request_code
        having count(*) > 1;
    ]
)

Спасибо

Изменить 1

Это работает благодаря Гордону Линоффу.

create unique index idx_trainingrule_4 on TRAINING_RULE (
         type, training_list_id, element_id, request_code,
         (case when after_rule is null and after_group is null then null
               else name
          end)
        );

person Artem.Borysov    schedule 01.09.2015    source источник


Ответы (2)


Я думаю, вы можете делать то, что хотите, с условным уникальным индексом. Это предполагает, что у вас есть уникальный столбец идентификатора в таблице (trainingrule_id), который никогда не бывает отрицательным:

create unique index idx_trainingrule_4 on (
         type, training_list_id, element_id, request_code,
         (case when after_rule is null and after_group is null then -1
               else trainingrule_id
          end)
        );
person Gordon Linoff    schedule 01.09.2015
comment
Ого, интересная конструкция. Но теперь я думаю о следующем: если принять во внимание группу +, имея конструкцию из моего основного оператора выбора (для этой цели stackoverflow.com/questions/32320217/< /а> ) - person Artem.Borysov; 01.09.2015

Вы не можете сделать это так. ДОБАВИТЬ ПРОВЕРОЧНОЕ ОГРАНИЧЕНИЕ:

  • Ограничение проверки НЕ МОЖЕТ быть определено в представлении SQL.
  • Ограничение проверки, определенное для таблицы, должно относиться только к столбцам этой таблицы. Он не может ссылаться на столбцы в других таблицах.
  • Ограничение проверки НЕ может включать подзапрос SQL.
  • Ограничение проверки может быть определено либо в операторе SQL CREATE TABLE, либо в операторе SQL ALTER TABLE.

Причина, по которой это работало ранее, заключалась в том, что вы применяли ограничение к значению столбца, которое является синтаксически правильным. Но последний не является правильным синтаксисом и не допускается.

person Rahul Tripathi    schedule 01.09.2015