我有两个表,一个是Customers和一个Sales表。 我正在尝试创建一个触发器,以便在更新Sales表时更新customer表中的销售量。
CREATE TRIGGER salesUPDATE
ON SALES
AFTER INSERT
AS
UPDATE Customers
SET salesAmount = Sales.Amount
GO
但我得知销售不存在。我应该使用加入吗? 这会触发更新所有列,还是需要指定要更新的列?
答案 0 :(得分:1)
CREATE TRIGGER salesUpdate ON SALES
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
;WITH cteAffectedCustomers AS (
SELECT DISTINCT CustomerId
FROM
inserted
UNION
SELECT DISTINCT CustomerId
FROM
deleted
)
, cteAggregations AS (
SELECT
ca.CustomerId
,SUM(ISNULL(s.Amount,0)) as SalesAmount
,COUNT(s.SalesId) as NumOfSales
FROM
cteAffectedCustomers ca
INNER JOIN Customers c
ON ca.CustomerId = c.CustomerId
LEFT JOIN Sales s
ON ca.CustomerId = s.CustomerId
GROUP BY
ca.CustomerId
)
UPDATE c
SET SalesAmount = ca.SalesAmount
,NumOfSales = ca.NumOfSales
FROM
Customers c
INNER JOIN cteAggregations ca
ON c.CustomerId = ca.CustomerId
END
以下是为维护预先聚合的值而需要创建的逻辑类型的示例。如果您想在SUM
表中Amount
Sales
,则需要AFTER INSERT, UPDATE, and DELETE
。然后你需要:
关于触发器的注释,它们是基于集合的操作而不是标量。这意味着它们为x#行触发一次,而不是x#行的x次。因此,您必须在更新期间考虑多个记录,并且在将一个表与另一个表更新时,就像在触发器外部一样进行连接。
这会对写入操作产生性能影响但会加快读取速度,但是如果您没有处理极高读取操作量,则最好使用视图/查询并优化索引。聚合数据同步的可能性越来越小。如果你确实采用了触发路径,我建议你在一些合理的增量(夜间)上设置一个SQL作业,检查并纠正可能发生的任何不一致。
答案 1 :(得分:0)
使用魔术表插入
CREATE TRIGGER salesUPDATE
ON SALES
AFTER INSERT
AS
BEGIN
Declare @Amount varchar(50) = (Select top 1 Amount from inserted)
UPDATE Customers
SET salesAmount = @Amount
END
GO
注意:前1位用于插入多条记录
答案 2 :(得分:-1)
使用包含新值的inserted
表名:
CREATE TRIGGER salesUPDATE
ON SALES
AFTER INSERT
AS
UPDATE Customers
SET salesAmount = inserted.Amount
GO