Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Usenet -> c.d.o.misc -> Re: Triggers
A copy of this was sent to flavoue_at_my-deja.com
(if that email address didn't require changing)
On Fri, 01 Oct 1999 14:32:19 GMT, you wrote:
>Hi,
>Here is my problem :
>I have one table that I would like to update automatically.
>I used triggers to do that but it doesn't work.
>
>Table :
>ID_objet Attribute Value
>
>A Z1 12
>A Z2 10
>A Z3 120 (12*10)
>
>B Z1 5
>B Z2 3
>B Z3 15 (5*3)
>
>I would like to calculate automatically the values 120 and 15 each time
>I insert an object
>X with the attributes Z1 and Z2.
>The help documentation of oracle says that I have to create 2 triggers,
>one (type : for each row) that insert in a temporary temble the value
>of the product and
>one that update (type : for statement) the table. The second doesn't
>work.
>Does any body know why?
>
very hazy details here. very very hazy.
Actually, to avoid the mutating table error, you can use 3 triggers and package (i find that better then a scratch table). You can see the URL in my signature for a howto on mutating tables.
You *probably* have a recursive error in your trigger. When you get to the AFTER statement trigger, you are going back to update that same table. That will fire your triggers again.
Here is an example that shows how to avoid the mutating table error, the recursion you will hit, and not use a temporary table:
tkyte_at_8.0> create table t ( id char(1), attr char(2), val int );
Table created.
tkyte_at_8.0> tkyte_at_8.0> tkyte_at_8.0> create or replace package t_state_pkg 2 as 3 type array is table of t.id%type index by binary_integer; 4 4 newones array; 5 empty array; 6 6 is_recursive boolean default FALSE;7 end;
Package created.
tkyte_at_8.0>
tkyte_at_8.0> create or replace trigger t_biu
2 before insert or update on T
3 begin
4 if ( NOT t_state_pkg.is_recursive ) 5 then 6 t_state_pkg.newones := t_state_pkg.empty ; 7 end if;
Trigger created.
tkyte_at_8.0>
tkyte_at_8.0> create or replace trigger t_aiufer
2 after insert or update on T for each row
3 begin
4 if ( NOT t_state_pkg.is_recursive ) 5 then 6 t_state_pkg.newones(t_state_pkg.newones.count+1) := :new.id; 7 end if;
Trigger created.
tkyte_at_8.0>
tkyte_at_8.0> create or replace trigger t_aiu
2 after insert or update on T
3 begin
4 if ( t_state_pkg.is_recursive ) then return; end if;
5
5 t_state_pkg.is_recursive := TRUE;
6
6 for i in 1 .. t_state_pkg.newones.count loop 7 update T 8 set val = ( select t1.val*t2.val 9 from t t1, t t2 10 where t1.id = t_state_pkg.newones(i) 11 and t1.attr = 'Z1' 12 and t2.id = t_state_pkg.newones(i) 13 and t2.attr = 'Z2' ) 14 where id = t_state_pkg.newones(i) 15 and attr = 'Z3'; 16 16 if ( sql%rowcount = 0 ) then 17 insert into t ( id, attr, val ) 18 select t_state_pkg.newones(i), 'Z3', t1.val*t2.val 19 from t t1, t t2 20 where t1.id = t_state_pkg.newones(i) 21 and t1.attr = 'Z1' 22 and t2.id = t_state_pkg.newones(i) 23 and t2.attr = 'Z2'; 24 end if; 25 end loop; 26 26 t_state_pkg.is_recursive := FALSE; 27 exception 28 when others then 29 t_state_pkg.is_recursive := FALSE; 30 RAISE;
Trigger created.
tkyte_at_8.0>
tkyte_at_8.0> insert into t values ( 'A', 'Z1', 12 );
1 row created.
tkyte_at_8.0> select * from t;
I AT VAL
- -- ----------
A Z1 12
tkyte_at_8.0> insert into t values ( 'A', 'Z2', 10 );
1 row created.
tkyte_at_8.0> select * from t;
I AT VAL
- -- ----------
A Z1 12 A Z2 10 A Z3 120
tkyte_at_8.0> insert into t values ( 'B', 'Z1', 5 );
1 row created.
tkyte_at_8.0> select * from t;
I AT VAL
- -- ----------
A Z1 12 A Z2 10 A Z3 120 B Z1 5
tkyte_at_8.0> insert into t values ( 'B', 'Z2', 3 );
1 row created.
tkyte_at_8.0> select * from t;
I AT VAL
- -- ----------
A Z1 12 A Z2 10 A Z3 120 B Z1 5 B Z2 3 B Z3 15
6 rows selected.
tkyte_at_8.0>
tkyte_at_8.0> update T set val = val+1 where attr in ( 'Z1', 'Z2' );
4 rows updated.
tkyte_at_8.0> select * from t;
I AT VAL
- -- ----------
A Z1 13 A Z2 11 A Z3 143 B Z1 6 B Z2 4 B Z3 24
6 rows selected.
>Thank you a lot for your help.
>
>
>Sent via Deja.com http://www.deja.com/
>Before you buy.
--
See http://osi.oracle.com/~tkyte/ for my columns 'Digging-in to Oracle8i'...
Current article is "Part I of V, Autonomous Transactions" updated June 21'st
Thomas Kyte tkyte_at_us.oracle.com Oracle Service Industries Reston, VA USA
Opinions are mine and do not necessarily reflect those of Oracle Corporation Received on Fri Oct 01 1999 - 11:00:57 CDT