微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用更新触发器获取主表中详细表字段的总和

如何解决如何使用更新触发器获取主表中详细表字段的总和

Firebird 3.0 数据库中有主表“factgad”和详细表“recgad”。

factgad:factgad_k(pr_k)...

recgad:recgad_k(pr_k)、factgad_k(fk)...

enter image description here

当我更新主表时,我必须得到明细表的记录总和,但我无法编写正确的代码。当我尝试更新主表时,出现错误

Error Message:
----------------------------------------
Too many concurrent executions of the same request.
Too many concurrent executions of the same request.
At trigger 'FACTGAD_AU' line: 21,col: 3
At trigger 'FACTGAD_AU' line: 21,co...
---------------------------------------------------
sqlCODE: -693
sqlSTATE: 54001
GDSCODE: 335544663



create or alter trigger factgad_AU FOR factgad
ACTIVE AFTER UPDATE POSITION 0
AS
DECLARE VARIABLE newl DECIMAL(8,4);
DECLARE VARIABLE oldl DECIMAL(8,4);
DECLARE VARIABLE newd DECIMAL(8,4);
DECLARE VARIABLE oldd DECIMAL(8,4);
DECLARE VARIABLE FACTGAD_K INTEGER;
BEGIN
 select
        f.factgad_k,sum(r.fnewl*r.rgad),sum(r.foldl*r.rgad),sum(r.fnewd*r.rgad),sum(r.foldd*r.rgad)
   from recgad r,factgad f
   where f.factgad_k=new.factgad_k and r.factgad_k=f.factgad_k
   group by f.factgad_k
   into  :factgad_k,:NEWL,:OLDL,:NEWD,:OLDD;

  update factgad set
    factgad.NEWL=:NEWL,factgad.OLDL=:OLDL,factgad.NEWD=:NEWD,factgad.OLDD=:OLDD
   where factgad_k=:FACTGAD_K;
end

触发器 sql 有什么问题?我尝试使用 where f.factgad_k=new.factgad_k 更改 where 子句 where f.factgad_k=43 但出现相同的错误。重新启动 Firebird 服务没有任何变化。

奇怪的行为,更新触发器后出现相同的错误,该触发器在更新明细表后使用明细表的总和更新主表:

CREATE OR ALTER TRIGGER RECGAD_AU FOR RECGAD
ACTIVE AFTER UPDATE POSITION 0
AS
DECLARE VARIABLE NEWL DECIMAL(8,4);
DECLARE VARIABLE OLDL DECIMAL(8,4);
DECLARE VARIABLE NEWD DECIMAL(8,4);
DECLARE VARIABLE OLDD DECIMAL(8,4);
DECLARE VARIABLE FACTGAD_K INTEGER;
begin
 select
        r.factgad_k,factgad f
   where r.factgad_k=new.factgad_k and r.factgad_k=f.factgad_k
   group by r.factgad_k
   into  :factgad_k,factgad.OLDD=:OLDD
   where factgad_k=:FACTGAD_K;
end 

解决方法

您正试图在更新表 blocks = int(input('Enter number of blocks:')) j = 0 i = 0 while i < blocks: i = i + 1 j = j + I if j > blocks: i =i-1 break height = I print("The height of the pyramid:",height) 时触发的触发器中更新表 FACTGAD。换句话说,更新触发触发器,哪个更新,哪个触发触发器等等。这最终会触发错误“同一请求的并发执行过多”

您不应在触发同一表更新的触发器中使用 FACTGAD。相反,您应该使用 UPDATE <table> 触发器,并将更新的值分配给 BEFORE UPDATE 上下文的列。在 NEWBEFORE UPDATE 上的 INSERT 触发器中,修改 UPDATE 上下文将更新要插入或更新的行。但是,在主表上触发的触发器中重新计算明细表中的值的总和没有多大意义:考虑如果主表从未更新,但添加、删除或更新明细行会发生什么情况。

至于您的第二个触发器,我只能猜测您在 NEW 上的触发器仍然存在,或者您有其他触发器导致 FACTGAD 和 {{1} 之间的更新循环}.

顺便说一句,您执行的选择不需要从 FACTGAD 中选择,假设您在两者之间有外键约束。

TLDR:删除触发器 RECGAD,保留触发器 FACTGAD(但考虑将其设为 factgad_AU)。

,

一般来说,主表中的详细记录的总和是不可能可靠的。最好的方法是通过详细表上的触发器添加和减去数据,但在负载下它最终会发生更新冲突。您的触发器将在并发环境中以完全错误的值结束。

通常在 select 中的聚合计算性能足够好。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。