Oracle PL/SQL触发器工作不正常

Oracle PL/SQL触发器工作不正常,oracle,plsql,triggers,Oracle,Plsql,Triggers,我的扳机有问题。创建触发器后,它会给我消息 BD1.UTILIZADOR正在变异,触发器无法读取或执行 我有这张桌子 create table UTILIZADOR ( U_ID NUMBER(6) not null, U_NOME VARCHAR2(60) not null, U_SEXO VARCHAR2(1

我的扳机有问题。创建触发器后,它会给我消息

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

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

您的触发器正在尝试更新一个已经被更新的行,想想看,在更新后的触发器中,您正在尝试进行另一次更新,这将再次触发触发器,导致另一次更新,然后再次触发触发器

Oracle不喜欢尝试更改或检查已经更改的内容


尝试直接在insert/update语句中设置u\u imc。

您的触发器代码正在更新
实用程序表中的每条记录,这将包括您的
insert
语句刚刚插入的记录,我假设您不希望在插入新记录时更新表中的每条记录

当您在insert或update之后触发FIELS时,它实际上会无限递归地调用自己,而您确实不希望这样

在你能有效地做你想做的事情之前,你需要对触发器有更多的了解

这是一篇关于改变表和触发器的好文章,其中有一些解决问题的建议:

可能有更好的方法来实现您的目标,例如,您可以在插入或更新
触发器之前使用
,并将更新分配给
:新的
值,而不是在触发器主体中发出新的
更新

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


希望对您有所帮助……

我假设您希望更新正在更新的记录的一个字段,而不是整个表上的字段:

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