所以我的老师在下面的代码中给了我错误的答案。他说这是不可能的。当我问他出了什么问题时,他只说这是显而易见的。我真的看不出有什么问题。我真的需要你的帮助,因为我的老师不会帮助我。
他唯一告诉我的部分是错的:
create or replace trigger aifer_deposit
after update or insert
of amount
on deposit
begin
update account
set saldo = saldo + (select amount from deposit);
end; 有人知道问题出在哪里吗?
发布于 2021-03-17 19:17:13
以下是我所看到的,仅从语法角度来看:
试试这个:
create or replace trigger aifer_deposit
after insert or update of amount
on deposit for each row
begin
update account set saldo = saldo + :new.amount;
end;也就是说,我在这里也看到了逻辑上的问题。如果没有主键,您的更新将把account表的每一行都更新为新值,而不仅仅是更新的帐户。另外,在此配置中,当存款更新时会发生什么?saldo的值总是通过新的值增加,而不是值的变化: saldo的值(我认为是帐户余额)将非常不准确。您需要使用复合触发器来区分插入和更新之间的逻辑。
发布于 2021-03-17 21:12:10
从语法上看,触发器正在工作。然而,从逻辑上讲,也有一些失败。
更新
update account set saldo = saldo + (select amount from deposit);很可能会失败,因为(select amount from deposit)要求返回一行,而实际情况很可能并非如此。此外,此语句还将更新表ACCOUNT中的所有行,这很可能也不是我们所希望的。
最有可能的情况是,您需要一个行级触发器。在本例中,您遗漏了FOR EACH ROW子句。但是你不能使用select amount from deposit,你不能在触发器中选择基表,这会引发著名的“变异表”错误。
所以,首先向你的老师询问你想要的逻辑,然后我们可以讨论错误的代码。
发布于 2021-03-17 22:29:18
通常,您需要的逻辑是:
update account
set saldo = saldo + coalesce(:new.amount, 0) - coalesce(:old.amount, 0);也就是说,减去旧值,然后加上新值。这就是如何维护累积总和。
https://stackoverflow.com/questions/66671211
复制相似问题