2011-11-23 70 views
2

我遇到触发器问题。创建触发器后,它给我的消息PL/SQL触发器无法正常工作

BD1.UTILIZADOR是突变,触发不能读取或执行

我有这个表

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) 
    ); 

,如果我这样做:

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'); 

然后

SELECT * FROM UTILIZADOR; 

我可以看到一切都如预期。

我想要做什么,插入或更新U_ALTURA或U_PESO时,字段U_IMC会自动更新/插入。

这里是如果做了什么:

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; 
/

有人能告诉我什么,我做错了什么?

回答

3

我假设你要更新的记录的字段被更新,而不是对整个表:

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; 
/
1

你的触发器试图更新一个已经更新的行,考虑一下,在你试图进行另一次更新的后期更新触发器中,它将再次触发触发器,导致另一个更新,然后触发触发器再次......

Oracle不喜欢试图改变或检查已经被改变的东西。

尝试直接在插入/更新语句中设置u_imc。

5

您的触发器代码正在更新UTILIZADOR表中的每条记录,这将包括您的INSERT语句刚刚插入的记录,我假设您不希望每当您插入新记录时更新表中的每条记录。

当你在插入或更新后触发火灾时,它实际上会递归地调用它自己,并且你真的不想这样做。

你需要更多地了解触发器,然后才能有效地做你想做的事情。

http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm

http://www.techonthenet.com/oracle/triggers/

这里是关于变异表一个伟大的文章,并提出一些建议触发器变圆了这个问题:

http://www.oracle-base.com/articles/9i/MutatingTableExceptions.php

有可能是一个更好的办法实现您的目标,例如您可以使用BEFORE INSERT OR UPDATE触发器并将更新分配给:NEW值而不是在您的触发器主体中发布新的UPDATE等。

行级别的触发器无法读取或写入从其触发的表。但是,语句级触发器可以。

希望它可以帮助...