Reputation: 7243
I have a problem with a trigger. After creating the trigger it gives me the message
BD1.UTILIZADOR is in mutation, trigger cant read or execute
I have this table
create table UTILIZADOR
(
U_ID NUMBER(6) not null,
U_NOME VARCHAR2(60) not null,
U_SEXO VARCHAR2(10) not null,
U_IDADE NUMBER(3) not null,
U_ALTURA NUMBER(3) not null,
U_PESO NUMBER(6) not null,
U_IMC NUMBER(2,2),
U_PRIVILEGIOS NUMBER(1) not null,
U_PASSWORD VARCHAR2(10) not null,
constraint PK_UTILIZADOR primary key (U_ID)
);
and If i do this:
INSERT INTO UTILIZADOR (U_ID,U_NOME,U_SEXO,U_IDADE,U_ALTURA,U_PESO,U_PRIVILEGIOS,U_PASSWORD) VALUES (1,'my name','Male',32,174,74000,0,'password');
and then
SELECT * FROM UTILIZADOR;
I can see that everything is as expected.
What I want to do, Is when inserting or updating U_ALTURA or U_PESO, the field U_IMC gets automatically updated/inserted.
Here is what if done:
CREATE OR REPLACE TRIGGER CALCULA_IMC
AFTER INSERT OR UPDATE OF U_ALTURA, U_PESO ON UTILIZADOR
FOR EACH ROW
BEGIN
UPDATE UTILIZADOR
SET U_IMC = (U_PESO / 1000) / (POWER(U_ALTURA / 100,2));
END;
/
Can someone please tell me what I'm doing wrong?
Upvotes: 2
Views: 4346
Reputation: 33273
I assume you want to update a field of the record being updated and not on the entire table:
CREATE OR REPLACE TRIGGER CALCULA_IMC
AFTER INSERT OR UPDATE OF U_ALTURA, U_PESO ON UTILIZADOR
FOR EACH ROW
BEGIN
:NEW.U_IMC = (:NEW.U_PESO / 1000) / (POWER(:NEW.U_ALTURA / 100,2));
END;
/
Upvotes: 3
Reputation: 17538
Your trigger code is updating every record in the UTILIZADOR
table, this would include the record your INSERT
statement has just inserted, I am assuming you don't want every record in your table updated whenever you insert a new record into it.
As you trigger fires after insert or update it is effectively going to recursively call itself infinitely and you really don't want that.
You need to understand a little more about triggers before you can effectively do what you want to do.
http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm
http://www.techonthenet.com/oracle/triggers/
Here is a great article about mutating tables and triggers with some suggestions for getting round the problem:
http://www.oracle-base.com/articles/9i/MutatingTableExceptions.php
There may well be a better way to achieve your goals, for example you could use a BEFORE INSERT OR UPDATE
trigger and assign the updates to the :NEW
values instead of issuing a new UPDATE
in your trigger body etc.
A row-level trigger can’t read or write the table it’s fired from. A statement-level trigger can, however.
Hope it helps...
Upvotes: 5
Reputation: 1081
Your trigger is attempting to update a row that's already being updated, think about it, in a post update trigger you're attempting to make another update which would fire the trigger again, causing another update which would then fire the trigger again.......
Oracle doesn't like trying to change or examine something that’s already being changed.
Try setting u_imc directly in your insert / update statements.
Upvotes: 1