Re: Update trigger
Date: Fri, 17 Oct 2008 07:11:53 -0700 (PDT)
Message-ID: <c1a46f04-8b2b-4d34-b8fd-22de923c632e@34g2000hsh.googlegroups.com>
On Oct 17, 7:33 am, ddf <orat..._at_msn.com> wrote:
> Comments embedded.
> On Oct 17, 5:37 am, phancey <d..._at_2bytes.co.uk> wrote:
>
>
>
> > On 17 Oct, 11:25, sybrandb <sybra..._at_gmail.com> wrote:
>
> > > On 17 okt, 12:00, phancey <d..._at_2bytes.co.uk> wrote:
>
> > > > hi,
>
> > > > I need to write a history record for certain fields that change on a
> > > > table. I am not sure whether it is better to write a single AFTER
> > > > UPDATE OF column1,column2,column3 etc trigger that then uses if
> > > > statements to check each specific field whether it has changed OR to
> > > > create an AFTER UPDATE OF column1 ON mytable WHEN nvl(new.column1,-1)
> > > > <> nvl(old.column1,-1) trigger for each column for example.
>
> > > > Is there a performance hit in having 7 AFTER UPDATE triggers defined,
> > > > one for each column I am interested in rather than 1 trigger for all
> > > > 7?
>
> > > > thanks for any help.
>
> > > > Phil
>
> > > Triggers are parsed on invocation. Obviously 1 parse is less expensive
> > > than 7 parses.
> > > If you just use
> > > IF updating('<column name>' then
> > > you wouldn't embark on creating a performance nightmare, which looks
> > > syntactically incorrect too.
>
> > > --
> > > Sybrand Bakker
> > > Senior Oracle DBA- Hide quoted text -
>
> > > - Show quoted text -
>
> > yes but it is only when the value changes that I should write the
> > history record. Rightly or wrongly the columns are all updated on a
> > record update even if we are only effectively changing one column
> > value (no point in discussing the merits of this as my hands are tied)
>
> That's incorrect.
>
> > - not strictly true as there are a couple of instances where updates
> > are more targeted hence my use of a column list in the trigger
> > definition but certainly the update of a column does not guarantee
> > that it is changing.
>
> But it does guarantee the value is changing unless the SET statement
> uses the existing value.
>
> > IF updating('<column name>') then..... would write the history record
> > every time the column was updated NOT, as required, when it was
> > changed?
>
DAvid,
I think he is saying the target columns are set in the update statement, but they may be set to their current value. If there is no actual change, he does not want the log entry. Personally, I would still want the log entry (otherwise the history is incomplete) and would filter it out on any reports that did not need it. So I ran a test and Phil is correct in that the update status does not check if the column really changes. I reran your test with an update that sets sal to the same value for some rows. The trigger also was changed to log if there is an actual value change for sal.
SQL> set linesize 72
SQL> drop trigger emp_upd_trig
Trigger dropped.
SQL> drop table emp
Table dropped.
SQL> create table emp (
empno number primary key,
ename varchar2(10),
job varchar2(10), sal number )
Table created.
SQL> insert into emp
select item_id,substr(item_desc,1,10),
decode(item_desc,'test','Tester','yyy','Bossman','worker') as job, 10000+item_id from ctfsapp.cont_dump_item 106 rows created.
SQL> commit
Commit complete.
SQL> select * from emp
EMPNO ENAME JOB SAL ---------- ---------- ---------- ----------
90 bbbbb worker 10090
93 test Tester 10093
94 test Tester 10094
100 test Tester 10100
101 st worker 10101
102 ste worker 10102
103 STOVE worker 10103
104 REFRIGERAT worker 10104
105 DISHWASHER worker 10105
63 1234567890 worker 10063
56 charmaine worker 10056
64 1234567890 worker 10064
65 1234567890 worker 10065
81 1234567890 worker 10081
88 yyy Bossman 10088
84 23234324 worker 10084
87 xxxxx worker 10087
92 hi worker 10092
99 stove worker 10099
57 microwave worker 10057
58 dishwasher worker 10058
EMPNO ENAME JOB SAL
---------- ---------- ---------- ----------
55 testing worker 10055
86 32 worker 10086
96 test Tester 10096
98 stove worker 10098
106 beer cans worker 10106
29 stove worker 10029
30 refrigerat worker 10030
59 dishwasher worker 10059
60 stove worker 10060
61 stove worker 10061
62 fridge worker 10062
66 1234567890 worker 10066
67 1234567890 worker 10067
68 1234567890 worker 10068
69 1234567890 worker 10069
70 1234567890 worker 10070
71 1234567890 worker 10071
72 1234567890 worker 10072
73 1234567890 worker 10073
74 1234567890 worker 10074
75 1234567890 worker 10075
EMPNO ENAME JOB SAL
---------- ---------- ---------- ----------
76 1234567890 worker 10076
77 1234567890 worker 10077
78 1234567890 worker 10078
79 1234567890 worker 10079
80 1234567890 worker 10080
91 hello worker 10091
107 asdf worker 10107
112 asfasfsafa worker 10112
122 DETAILED D worker 10122
139 11241 worker 10139
149 oops worker 10149
151 xxx worker 10151
156 3rtr worker 10156
157 trash worker 10157
161 What is th worker 10161
116 DETAILED D worker 10116
117 DETAILED D worker 10117
118 DETAILED D worker 10118
119 DETAILED D worker 10119
120 DETAILED D worker 10120
121 DETAILED D worker 10121
EMPNO ENAME JOB SAL
---------- ---------- ---------- ----------
134 0123456789 worker 10134
142 0123456789 worker 10142
143 (e.g. refr worker 10143
144 (e.g. refr worker 10144
145 asfasfsad worker 10145
146 DETAILED D worker 10146
152 a worker 10152
154 x worker 10154
1805 bbbbb worker 11805
108 333414 worker 10108
109 test Tester 10109
113 Test dump worker 10113
114 asfsafasfa worker 10114
115 DETAILED D worker 10115
125 asfasfas worker 10125
135 9911048921 worker 10135
136 13414141 worker 10136
137 asdf worker 10137
138 11241 worker 10138
140 DETAILED D worker 10140
141 0123456789 worker 10141
EMPNO ENAME JOB SAL
---------- ---------- ---------- ----------
37996 ssss worker 47996
38015 testing 40 worker 48015
147 Railroad T worker 10147
148 asdf worker 10148
150 Test worker 10150
158 grass clip worker 10158
124 DETAILED D worker 10124
126 DETAILED D worker 10126
127 refrigerat worker 10127
128 stoves worker 10128
129 dishwasher worker 10129
130 as worker 10130
133 dishwasher worker 10133
153 TEST worker 10153
155 OK worker 10155
159 junk worker 10159
110 test Tester 10110
111 1134131414 worker 10111
123 DETAILED D worker 10123
131 refrigerat worker 10131
132 dishwasher worker 10132
EMPNO ENAME JOB SAL
---------- ---------- ---------- ----------
160 complete d worker 10160
106 rows selected.
SQL> drop table emp_hist
Table dropped.
SQL> create table emp_hist
as select empno, ename, job, sal from emp where 0=1
Table created.
SQL> alter table emp_hist add (chg_user varchar2(30), chg_dt date,
action varchar2(40))
Table altered.
SQL> create or replace trigger emp_upd_trig
after update of ename, job, sal on emp
for each row
begin
if updating('ename') then
insert into emp_hist(empno, ename, chg_user,
chg_dt,action)
values (:new.empno, :new.ename, user, sysdate,
'UPDATE');
elsif updating('job') then
insert into emp_hist(empno, job, chg_user, chg_dt,
action)
values (:new.empno, :new.job, user, sysdate,
'UPDATE');
elsif updating('sal') then
insert into emp_hist(empno, sal, chg_user, chg_dt,
action)
values (:new.empno, :new.sal, user, sysdate,
'UPDATE');
IF :new.sal = :old.sal THEN
NULL;
ELSE
insert into emp_hist(empno, sal, chg_user,
chg_dt, action)
values (:new.empno, :new.sal, user, sysdate,
'SAL '||:old.sal||'->'||:new.sal);
END IF;
end if;
end;
Trigger created.
SQL> select count(*) from emp where empno>150
COUNT(*)
14
1 row selected.
SQL> update emp set sal = sal*1.1 where empno>150
14 rows updated.
SQL> update emp set sal = 60000 where job='Tester'
6 rows updated.
SQL> commit
Commit complete.
SQL> select empno, sal, action from emp_hist
EMPNO SAL ACTION
---------- ---------- ----------------------------------------
151 11166.1 UPDATE
151 11166.1 SAL 10151->11166.1
152 11167.2 UPDATE
152 11167.2 SAL 10152->11167.2
153 11168.3 UPDATE
153 11168.3 SAL 10153->11168.3
154 11169.4 UPDATE
154 11169.4 SAL 10154->11169.4
155 11170.5 UPDATE
155 11170.5 SAL 10155->11170.5
156 11171.6 UPDATE
156 11171.6 SAL 10156->11171.6
157 11172.7 UPDATE
157 11172.7 SAL 10157->11172.7
158 11173.8 UPDATE
158 11173.8 SAL 10158->11173.8
159 11174.9 UPDATE
159 11174.9 SAL 10159->11174.9
160 11176 UPDATE
160 11176 SAL 10160->11176
161 11177.1 UPDATE
EMPNO SAL ACTION
---------- ---------- ----------------------------------------
161 11177.1 SAL 10161->11177.1
1805 12985.5 UPDATE
1805 12985.5 SAL 11805->12985.5
37996 52795.6 UPDATE
37996 52795.6 SAL 47996->52795.6
38015 52816.5 UPDATE
38015 52816.5 SAL 48015->52816.5
93 60000 UPDATE
93 60000 SAL 10093->60000
94 60000 UPDATE
94 60000 SAL 10094->60000
100 60000 UPDATE
100 60000 SAL 10100->60000
96 60000 UPDATE
96 60000 SAL 10096->60000
109 60000 UPDATE
109 60000 SAL 10109->60000
110 60000 UPDATE
110 60000 SAL 10110->60000
40 rows selected.
SQL> update emp set sal = 60000 where job='Tester'
6 rows updated.
SQL> commit
Commit complete.
SQL> select empno, sal, action from emp_hist
EMPNO SAL ACTION
---------- ---------- ----------------------------------------
151 11166.1 UPDATE
151 11166.1 SAL 10151->11166.1
152 11167.2 UPDATE
152 11167.2 SAL 10152->11167.2
153 11168.3 UPDATE
153 11168.3 SAL 10153->11168.3
154 11169.4 UPDATE
154 11169.4 SAL 10154->11169.4
155 11170.5 UPDATE
155 11170.5 SAL 10155->11170.5
156 11171.6 UPDATE
156 11171.6 SAL 10156->11171.6
157 11172.7 UPDATE
157 11172.7 SAL 10157->11172.7
158 11173.8 UPDATE
158 11173.8 SAL 10158->11173.8
159 11174.9 UPDATE
159 11174.9 SAL 10159->11174.9
160 11176 UPDATE
160 11176 SAL 10160->11176
161 11177.1 UPDATE
EMPNO SAL ACTION
---------- ---------- ----------------------------------------
161 11177.1 SAL 10161->11177.1
1805 12985.5 UPDATE
1805 12985.5 SAL 11805->12985.5
37996 52795.6 UPDATE
37996 52795.6 SAL 47996->52795.6
38015 52816.5 UPDATE
38015 52816.5 SAL 48015->52816.5
93 60000 UPDATE
93 60000 SAL 10093->60000
94 60000 UPDATE
94 60000 SAL 10094->60000
100 60000 UPDATE
100 60000 SAL 10100->60000
96 60000 UPDATE
96 60000 SAL 10096->60000
109 60000 UPDATE
109 60000 SAL 10109->60000
110 60000 UPDATE
110 60000 SAL 10110->60000
93 60000 UPDATE
94 60000 UPDATE
EMPNO SAL ACTION
---------- ---------- ----------------------------------------
100 60000 UPDATE
96 60000 UPDATE
109 60000 UPDATE
110 60000 UPDATE
46 rows selected. Received on Fri Oct 17 2008 - 09:11:53 CDT
