Skip to content

Commit 865aac4

Browse files
committed
Fix #84 - Created rule G-7730: Avoid multiple DML events per trigger if primary key is assigned in trigger.
1 parent e10f537 commit 865aac4

File tree

1 file changed

+62
-0
lines changed
  • docs/4-language-usage/7-stored-objects/7-triggers

1 file changed

+62
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# G-7730: Avoid multiple DML events per trigger if primary key is assigned in trigger.
2+
3+
!!! warning "Major"
4+
Efficiency, Reliability
5+
6+
## Reason
7+
8+
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.
9+
10+
## Example (bad)
11+
12+
``` sql
13+
create or replace trigger dept_br_iu
14+
before insert or update
15+
on departments for each row
16+
begin
17+
if inserting then
18+
:new.department_id := department_seq.nextval;
19+
:new.created_date := sysdate;
20+
end if;
21+
if updating then
22+
:new.changed_date := sysdate;
23+
end if;
24+
end;
25+
/
26+
```
27+
28+
## Example (better)
29+
30+
``` sql
31+
create or replace trigger dept_br_i
32+
before insert
33+
on departments for each row
34+
begin
35+
:new.department_id := department_seq.nextval;
36+
:new.created_date := sysdate;
37+
end;
38+
/
39+
40+
create or replace trigger dept_br_u
41+
before update
42+
on departments for each row
43+
begin
44+
:new.changed_date := sysdate;
45+
end;
46+
/
47+
```
48+
49+
## Example (good)
50+
51+
``` sql
52+
alter table department modify department_id default on null department_seq.nextval;
53+
alter table department modify created_date default on null sysdate;
54+
55+
create or replace trigger dept_br_u
56+
before update
57+
on departments for each row
58+
begin
59+
:new.changed_date := sysdate;
60+
end;
61+
/
62+
```

0 commit comments

Comments
 (0)