如何在 SQL 中使用触发器来更新一行,基于另外两行
Posted
技术标签:
【中文标题】如何在 SQL 中使用触发器来更新一行,基于另外两行【英文标题】:How to use a trigger in SQL to update a row, based in two other rows 【发布时间】:2019-11-24 12:24:11 【问题描述】:也许这太简单了,但我对这项任务感到头疼,我正在为一些作业建立一个健身房数据库,我必须分别根据名为身高和体重的其他行计算 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.
它不起作用,如果有人带我看一些内容来学习如何正确执行此操作,我将不胜感激,因为我被卡住了
【问题讨论】:
【参考方案1】:假设您使用标准 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;
这是一个“之前”触发器。它只是设置新值进行计算。不需要更新,因为您想更改正在更新的同一个表的同一行中的列值。
Here 是一个展示它的实验者。
【讨论】:
create or replace trigger calculate_bmi before insert or update on evaluation begin :new.bmi = :new.weight/ (:new.height*:new.height); end;
我试过了,但返回 ORA-04082: NEW or OLD references not allowed in table level trigger
@GabrieRabelo 。 . .触发器需要for each row
。我还修正了一个错字并添加了一个工作示例。【参考方案2】:
您需要指定是要更改现在更新的新值还是旧值。
例如:
set new.BMI = i.bmi, weight = new.weight(height*height)
【讨论】:
【参考方案3】:您的代码有问题:
触发器无法操作触发它的表;您确实需要设置 bmi
的 before
触发器,而不是尝试更新表 evaluation
的 after
触发器
您的触发器应该逐行触发,而不是在语句级别触发(因此它需要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
【讨论】:
我试过这个:```在插入或更新每一行的评估之前创建或替换触发器calculate_bmi 开始:new.bmi = :new.weight / (:new.height * :new 。高度); end ``` 但它也不起作用,它正在返回 Encountered the symbol "=" 当期待以下之一时::= 。 ( @ % ; 指示符 在预期以下情况之一时遇到符号“;”:) , * & - + / at mod remaining rem and or ||年日 @GabrieRabelo:抱歉,它必须是:new.bmi :=
而不是 set :new.bmi =
。固定。以上是关于如何在 SQL 中使用触发器来更新一行,基于另外两行的主要内容,如果未能解决你的问题,请参考以下文章