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
子句中,这意味着它通常需要在 JOIN
ed 中。在你的 UPDATE
语句,inserted
在子查询和外部查询中都需要,所以它被加入到外部查询中。
【讨论】:
您需要更具体。它做了什么?什么结果?有任何错误信息吗? 我修改了我创建的触发器并使用了您编写的触发器。然后我更新了接收器的统计数据,为 DEN、PIT 和 SEA 上的所有接收器添加了 50 码。然而,当我查看四分卫的数据时,他们的码数增加太多了。 实际上它开始起作用了。在子选择中,我只需要指定 Widereceivers.Yards 和 Widereceivers.Team。它按我想要的方式工作。非常感谢您的帮助:) 我对子选择的经验有限,而且我从来没有想过这样做。我能问一下子选择到底在做什么吗? 如果我想在我的任何更新语句中引用插入/删除表,是否需要加入?以上是关于AFTER UPDATE 触发器使用更新表中的聚合的主要内容,如果未能解决你的问题,请参考以下文章