如何在SQL中使用触发器来更新基于另外两行的行

问题描述 投票:1回答:3

也许这太简单了,但我对此任务感到头疼,我正在为一些家庭作业建立一个健身房数据库,我必须根据分别名为高度和体重的其他行来计算BMI。我不知道更新此表的方法,我已经尝试过

create or replace trigger calculate_BMI
after insert or update on evaluation
begin
    update evaluation
    set BMI = i.bmi, weight = weight(height*height)
    from inserted as i
end

这就是我所发现的

SQL Error: ORA-04098: trigger 'BJ111237.CALCULATE_BMI' is invalid and failed re-validation
04098. 00000 -  "trigger '%s.%s' is invalid and failed re-validation"
*Cause:    A trigger was attempted to be retrieved for execution and was
           found to be invalid.  This also means that compilation/authorization
           failed for the trigger.
*Action:   Options are to resolve the compilation/authorization errors,
           disable the trigger, or drop the trigger.

这是行不通的,如果有人将我带到一些内容来学习如何正确执行此操作,我会被卡住,我将不胜感激

sql oracle triggers oracle-sqldeveloper
3个回答
0
投票

您需要指定是否要更改现在更新的新值或旧值。

例如:

set new.BMI = i.bmi, weight = new.weight(height*height)

0
投票

您的代码有问题:

  • 触发器无法操作对其触发的表;您确实想要一个before触发器来设置bmi,而不是一个after触发器来尝试更新表evaluation

  • 您的触发器应该逐行触发,而不是在语句级别触发(因此它需要for each row选项)]] >>

  • 伪表inserted在Oracle中不存在;相反,您可以使用:new.访问为更新或插入而传递的值

  • 您可能想要:

create or replace trigger calculate_bmi
after insert or update on evaluation
for each row
begin
    :new.bmi := :new.weight / (:new.height * :new.height);
end

假设您使用的是标准BMI计算,并且您的值使用适当的单位存储,那么更新的Oracle语法为:

create or replace trigger calculate_BMI
before insert or update on evaluation
for each row
begin
    :new.bmi = :new.weight / (:new.height * :new.height);
end;

这是“之前”触发器。它只是通过计算来设置新值。不需要更新,因为您要更改要更新的同一张表的同一行中的列值。


0
投票

假设您使用的是标准BMI计算,并且您的值使用适当的单位存储,那么更新的Oracle语法为:

© www.soinside.com 2019 - 2024. All rights reserved.