Я думаю, что я не согласен с вашим описанием того, что пытается сделать триггер
делать. Мне кажется, что это должно обеспечить соблюдение этого бизнес-правила: для
При заданном значении t1_appnt_event только одна строка может иметь ненулевое значение
t1_prnt_t1_pk одновременно. (Неважно, имеют ли они одинаковое значение во втором столбце или нет.)
Интересно, что он определен для UPDATE OF t1_appnt_event, но не для другого столбца, поэтому я думаю, что кто-то может нарушить правило, обновив второй столбец, если только для этого столбца не предусмотрен отдельный триггер.
Возможно, вы могли бы создать индекс на основе функций, который бы применял это правило, чтобы вы могли полностью избавиться от триггера. Я придумал один способ, но он требует некоторых предположений:
- Таблица имеет числовой первичный ключ
- Первичный ключ и t1_prnt_t1_pk всегда являются положительными числами
Если эти предположения верны, вы можете создать такую функцию:
dev> create or replace function f( a number, b number ) return number deterministic as
2 begin
3 if a is null then return 0-b; else return a; end if;
4 end;
и такой индекс:
CREATE UNIQUE INDEX my_index ON my_table
( t1_appnt_event, f( t1_prnt_t1_pk, primary_key_column) );
Таким образом, строки, в которых столбец PMNT равен NULL, будут появляться в индексе с обратным первичным ключом в качестве второго значения, поэтому они никогда не будут конфликтовать друг с другом. Строки, где оно не равно NULL, будут использовать фактическое (положительное) значение столбца. Единственный способ получить нарушение ограничения - это если в двух столбцах одинаковые значения, отличные от NULL, в обоих столбцах.
Возможно, это слишком "умно", но это может помочь вам обойти вашу проблему.
Обновление от Пола Томблина: я пошел с обновлением к оригинальной идее, которую Игорь вложил в комментарии:
CREATE UNIQUE INDEX cappec_ccip_uniq_idx
ON tbl1 (t1_appnt_event,
CASE WHEN t1_prnt_t1_pk IS NOT NULL THEN 1 ELSE t1_pk END);