Skip to content

G-7730: Avoid multiple DML events per trigger if primary key is assigned in trigger.

Major

Efficiency, Reliability

Reason

If a trigger makes assignment to the primary key anywhere in the trigger code, that causes the session firing the trigger to take a lock on any child tables with a foreign key to this primary key. Even if the assignment is in for example an if inserting block and the trigger is fired by an update statement, such locks still happen unnecessarily. The issue is avoided by having one trigger for the insert containing the primary key assignment, and another trigger for the update. Or even better by handling the insert assignment as ´default on null´ clauses, so that only an on update trigger is needed.

Example (bad)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
create or replace trigger dept_br_iu
before insert or update
on departments for each row
begin
   if inserting then
      :new.department_id := department_seq.nextval;
      :new.created_date  := sysdate;
   end if;
   if updating then
      :new.changed_date  := sysdate;
   end if;
end;
/

Example (better)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
create or replace trigger dept_br_i
before insert
on departments for each row
begin
   :new.department_id := department_seq.nextval;
   :new.created_date  := sysdate;
end;
/

create or replace trigger dept_br_u
before update
on departments for each row
begin
   :new.changed_date  := sysdate;
end;
/

Example (good)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
alter table department modify department_id default on null department_seq.nextval;
alter table department modify created_date  default on null sysdate;

create or replace trigger dept_br_u
before update
on departments for each row
begin
   :new.changed_date  := sysdate;
end;
/