首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >老师告诉我这是错的

老师告诉我这是错的
EN

Stack Overflow用户
提问于 2021-03-17 18:28:44
回答 3查看 67关注 0票数 0

所以我的老师在下面的代码中给了我错误的答案。他说这是不可能的。当我问他出了什么问题时,他只说这是显而易见的。我真的看不出有什么问题。我真的需要你的帮助,因为我的老师不会帮助我。

他唯一告诉我的部分是错的:

代码语言:javascript
复制
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; 

有人知道问题出在哪里吗?

EN

回答 3

Stack Overflow用户

发布于 2021-03-17 19:17:13

请查看文档中的语法:https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/CREATE-TRIGGER-statement.html#GUID-AF9E33F1-64D1-4382-A6A4-EC33C36F237B

以下是我所看到的,仅从语法角度来看:

  1. 缺少"for each row“子句
  2. "on column”子句必须跟在"on update“not”insert“
  3. 触发器不能引用它在查询中附加到的表。当触发器执行时,你会得到一个"mutating table“错误。使用内置绑定变量引用行中金额的新值。

试试这个:

代码语言:javascript
复制
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的值(我认为是帐户余额)将非常不准确。您需要使用复合触发器来区分插入和更新之间的逻辑。

票数 0
EN

Stack Overflow用户

发布于 2021-03-17 21:12:10

从语法上看,触发器正在工作。然而,从逻辑上讲,也有一些失败。

更新

代码语言:javascript
复制
update account set saldo = saldo + (select amount from deposit);

很可能会失败,因为(select amount from deposit)要求返回一行,而实际情况很可能并非如此。此外,此语句还将更新表ACCOUNT中的所有行,这很可能也不是我们所希望的。

最有可能的情况是,您需要一个行级触发器。在本例中,您遗漏了FOR EACH ROW子句。但是你不能使用select amount from deposit,你不能在触发器中选择基表,这会引发著名的“变异表”错误。

所以,首先向你的老师询问你想要的逻辑,然后我们可以讨论错误的代码。

票数 0
EN

Stack Overflow用户

发布于 2021-03-17 22:29:18

通常,您需要的逻辑是:

代码语言:javascript
复制
    update account
        set saldo = saldo + coalesce(:new.amount, 0) - coalesce(:old.amount, 0);

也就是说,减去旧值,然后加上新值。这就是如何维护累积总和。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66671211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档