I think I disagree with your description of what the trigger is trying to do. It seems to me that it is designed to enforce this business rule: for a given value of t1_appnt_event, only one line can have a non-NULL value of t1_prnt_t1_pk at a time. (It doesn't matter if they have the same value in the second column or not.)
Interestingly, it is defined for UPDATE OF t1_appnt_event, but not for another column, so I think someone can break the rule by updating the second column if there is no separate trigger for this column.
Perhaps you can create an index based on functions that will apply this rule to completely get rid of the trigger. I came up with one way, but it requires some assumptions:
- Table has a numerical primary key
- The primary key and t1_prnt_t1_pk are both always positive numbers
If these assumptions are true, you can create a function like this:
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;
and an index like this:
CREATE UNIQUE INDEX my_index ON my_table ( t1_appnt_event, f( t1_prnt_t1_pk, primary_key_column) );
Thus, rows in which the PMNT column is NULL will be displayed in the index with the primary key inverted as the second value, so they never conflict with each other. Rows where it is not NULL will use the actual (positive) value of the column. The only way you could get a constraint violation would be for the two rows to have the same non-NULL values โโin both columns.
It may be too smart, but it can help you solve your problem.
Update from Paul Tomblin: I went with an update to the original idea that igor added in the comments:
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);
Dave costa
source share