AFTER UPDATE 触发器使用更新表中的聚合

Posted

技术标签:

【中文标题】AFTER UPDATE 触发器使用更新表中的聚合【英文标题】:AFTER UPDATE trigger using an aggregate from the updated table 【发布时间】:2013-12-19 02:25:16 【问题描述】:

我在使用更新触发器时遇到问题。如果他们在同一支球队,我希望触发器将Quarterbacks.Yards 设置为等于宽接收码的总和。

create trigger T_Receiving_Passing
on NFL.Widereceivers
after update
as
begin
declare
@receivingyards int,

select @receivingyards = sum (Widereceivers.Yards) from NFL.Widereceivers
update NFL.Quarterbacks
set Quarterbacks.Yards = @receivingyards
where Quarterbacks.Team = Widereceivers.Team
end

在语句的末尾,Widereceivers.Team 带有红色下划线,它会导致错误。每当我尝试引用另一个表中的列而不在from 子句中命名该表时,我都会遇到同样的错误。我该如何解决这个问题?

【问题讨论】:

在编辑代码块时,您可以突出显示整个内容并单击工具栏中的,或 ctl-k 将块缩进 4 个空格保留空白。 如何确定要更新的团队?您的select 没有GROUP BY,因此您将获得所有行的总SUM()。是不是应该按团队分组? RDBMS 的用途是什么——它看起来或多或少像 mysql 我使用的是 SQL Server 2012 我应该把分组放在哪里? 是的,它应该按团队分组。我会把它放在我给变量值的语句中吗? 【参考方案1】:

好的,您应该能够在不使用 SELECT 语句或其变量的情况下执行此操作,而是使用更复杂的 UPDATE 语句加入特殊的 inserted 表,该表包含更新中的新值。

CREATE TRIGGER T_Receiving_Passing
ON NFL.Widereceivers
AFTER UPDATE
AS
  UPDATE NFL.Quarterbacks
  -- Get the SUM() in a subselect
  SET Quarterbacks.Yards = (SELECT SUM(Yards) FROM Widereceivers WHERE Team = inserted.Team) 
  FROM 
    NFL.Quarterbacks
    -- Join against the special inserted table
    JOIN inserted ON Quarterbacks.Team = inserted.Team
GO

Here is a proof of concept

在您最初的尝试中,您希望首先使用SELECT 查询来填充标量变量。但是,在UPDATE 语句中,您可以使用子选择在SET 子句中返回恰好一行中的一列来检索新值。

由于您的要求是使用聚合 SUM(),因此它不像直接从 inserted 分配值(如 SET Yards = inserted.Yards)那么简单。相反,子选择生成的总和仅限于inserted 行中使用的Team

inserted/deleted 表而言,review the official documentation。几年来我没有定期使用 SQL Server,但如果我没记错的话,inserted 表必须出现在 FROM 子句中,这意味着它通常需要在 JOINed 中。在你的 UPDATE语句,inserted 在子查询和外部查询中都需要,所以它被加入到外部查询中。

【讨论】:

您需要更具体。它做了什么?什么结果?有任何错误信息吗? 我修改了我创建的触发器并使用了您编写的触发器。然后我更新了接收器的统计数据,为 DEN、PIT 和 SEA 上的所有接收器添加了 50 码。然而,当我查看四分卫的数据时,他们的码数增加太多了。 实际上它开始起作用了。在子选择中,我只需要指定 Widereceivers.Yards 和 Widereceivers.Team。它按我想要的方式工作。非常感谢您的帮助:) 我对子选择的经验有限,而且我从来没有想过这样做。我能问一下子选择到底在做什么吗? 如果我想在我的任何更新语句中引用插入/删除表,是否需要加入?

以上是关于AFTER UPDATE 触发器使用更新表中的聚合的主要内容,如果未能解决你的问题,请参考以下文章

在AFTER UPDATE触发器上尝试更新只读列错误

条件AFTER UPDATE触发器

AFTER UPDATE 触发器上的变异表错误

SQL AFTER 插入更新触发器

postgreSQL创建一个触发器函数:更新过student1表的数据后,更新student1_stats表中数据。

对于50000行的表,MySQL触发器AFTER UPDATE执行速度极慢