SQL: 触发器没有收集每一行
SQL: Trigger is not collecting every row
我的触发器有问题,当我在另一个 table 中有新行时应该更新一个 table。
我有两个 table:
第一个:
SELECT
[Id], [Timestamp], [MachineName], [StatusId], [Quantity]
FROM [dbo].[Events]
第二个:
SELECT
[Id], [MachineName], [StatusId], [QuantitySum], [StatusLastRefresh]
FROM [dbo].[ActualParams]
到 table [Events]
每台机器上的每个状态更改都来自流分析。对于每个新行,第二个 table 应该更新并显示每台机器的最后一个值,最后一个时间戳在 StatusLastRefresh 中。实际上table[ActualParams]
有4行数据
我已经尝试了 2 个触发器:
ALTER TRIGGER [dbo].[AfterInsertEvent]
ON [dbo].[Events]
AFTER INSERT
AS
MERGE ActualParams AS ap
USING (SELECT Id, Machine, Status, Timestamp, Quantity
FROM inserted) AS ev ON ev.MachineName = ap.MachineName
WHEN MATCHED THEN
UPDATE SET map.StatusId = ev.StatusId,
ap.StatusLastRefresh = ev.Timestamp,
ap.QuantitySum = ap.QuantitySum + ev.Quantity;
触发器#2:
ALTER TRIGGER [dbo].[AfterInsertEvent]
ON [dbo].[Events]
AFTER INSERT
BEGIN
DECLARE @mn nchar(10), @si int, @ts datetime2(7), @q int
SELECT @mn = MachineName, @si = StatusId, @ts = Timestamp, @q = Quantity
FROM inserted
UPDATE ActualParams
SET StatusId = @si,
StatusLastRefresh = @ts,
QuantitySum = QuantitySum + @q
WHERE ActualParams.MachineName = @mn
END
但其中 none 100% 正确。
首先,当每个 MachineName
插入的行同时插入一个行时,Merge
触发器工作正常,但有时对于相同的 [=18],同时插入的行很少=] 已插入,我收到一个错误,它无法同时将多行写入一个行,一切都卡住了。
其次,更简单的 Update
触发器有时会跳过一行,并且在 ActualParams table 中有以前的 StatusId 值,而不是实际值。实际上我有 4 台机器,通常其中一台有错误的 StatusId。我想知道当有20台或更多台机器时会发生什么。
MachineName
对每台机器都是唯一的。
我尝试使用 CURSOR 和 UPDATE,但有时仍然会跳过该行,并且状态不真实。
我不知道如何将 CURSOR 与 MERGE 结合使用,也许这就是解决方案。
它必须对每一行做出反应,因为我还想在第二个 table 中汇总数量,所以这就是为什么我不能跳过任何行(之前忘记了 - 已编辑)
有什么想法吗?我正在使用 SSMS 17。
你为什么不直接用 update
/join
来写呢?
UPDATE ap
SET StatusId = i.StatusId,
StatusLastRefresh = i.TimeStamp
FROM ActualParams ap
inserted i
ON ap.MachineName = i.MachineName;
如果同一台机器可以在一台insert
中更新多次,则使用window函数获取最后一行:
UPDATE ap
SET StatusId = i.StatusId,
StatusLastRefresh = i.TimeStamp
FROM ActualParams ap
(SELECT i.*,
ROW_NUMBER() OVER (PARTITION BY MachineName ORDER BY TimeStamp DESC) as seqnum
FROM inserted i
) i
ON ap.MachineName = i.MachineName AND seqnum = 1;
我的触发器有问题,当我在另一个 table 中有新行时应该更新一个 table。
我有两个 table:
第一个:
SELECT
[Id], [Timestamp], [MachineName], [StatusId], [Quantity]
FROM [dbo].[Events]
第二个:
SELECT
[Id], [MachineName], [StatusId], [QuantitySum], [StatusLastRefresh]
FROM [dbo].[ActualParams]
到 table [Events]
每台机器上的每个状态更改都来自流分析。对于每个新行,第二个 table 应该更新并显示每台机器的最后一个值,最后一个时间戳在 StatusLastRefresh 中。实际上table[ActualParams]
有4行数据
我已经尝试了 2 个触发器:
ALTER TRIGGER [dbo].[AfterInsertEvent]
ON [dbo].[Events]
AFTER INSERT
AS
MERGE ActualParams AS ap
USING (SELECT Id, Machine, Status, Timestamp, Quantity
FROM inserted) AS ev ON ev.MachineName = ap.MachineName
WHEN MATCHED THEN
UPDATE SET map.StatusId = ev.StatusId,
ap.StatusLastRefresh = ev.Timestamp,
ap.QuantitySum = ap.QuantitySum + ev.Quantity;
触发器#2:
ALTER TRIGGER [dbo].[AfterInsertEvent]
ON [dbo].[Events]
AFTER INSERT
BEGIN
DECLARE @mn nchar(10), @si int, @ts datetime2(7), @q int
SELECT @mn = MachineName, @si = StatusId, @ts = Timestamp, @q = Quantity
FROM inserted
UPDATE ActualParams
SET StatusId = @si,
StatusLastRefresh = @ts,
QuantitySum = QuantitySum + @q
WHERE ActualParams.MachineName = @mn
END
但其中 none 100% 正确。
首先,当每个 MachineName
插入的行同时插入一个行时,Merge
触发器工作正常,但有时对于相同的 [=18],同时插入的行很少=] 已插入,我收到一个错误,它无法同时将多行写入一个行,一切都卡住了。
其次,更简单的 Update
触发器有时会跳过一行,并且在 ActualParams table 中有以前的 StatusId 值,而不是实际值。实际上我有 4 台机器,通常其中一台有错误的 StatusId。我想知道当有20台或更多台机器时会发生什么。
MachineName
对每台机器都是唯一的。
我尝试使用 CURSOR 和 UPDATE,但有时仍然会跳过该行,并且状态不真实。
我不知道如何将 CURSOR 与 MERGE 结合使用,也许这就是解决方案。
它必须对每一行做出反应,因为我还想在第二个 table 中汇总数量,所以这就是为什么我不能跳过任何行(之前忘记了 - 已编辑)
有什么想法吗?我正在使用 SSMS 17。
你为什么不直接用 update
/join
来写呢?
UPDATE ap
SET StatusId = i.StatusId,
StatusLastRefresh = i.TimeStamp
FROM ActualParams ap
inserted i
ON ap.MachineName = i.MachineName;
如果同一台机器可以在一台insert
中更新多次,则使用window函数获取最后一行:
UPDATE ap
SET StatusId = i.StatusId,
StatusLastRefresh = i.TimeStamp
FROM ActualParams ap
(SELECT i.*,
ROW_NUMBER() OVER (PARTITION BY MachineName ORDER BY TimeStamp DESC) as seqnum
FROM inserted i
) i
ON ap.MachineName = i.MachineName AND seqnum = 1;