inserted
是一个伪表,它肯定包含受该UPDATE
语句影响的所有正确行(DISTINCT
如果主键,我认为不是必需ID
的 - 尽管很难分辨名称为 的表是什么121s
)。在应用修改后的日期/时间之前,您可以考虑验证它们是否都实际更改了值。除此之外,我可能会这样做:
ALTER TRIGGER [dbo].[trg_121s]
ON [dbo].[121s]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE t SET modified = CURRENT_TIMESTAMP
FROM dbo.[121s] AS t
WHERE EXISTS (SELECT 1 FROM inserted WHERE ID = t.ID);
-- WHERE EXISTS is same as INNER JOIN inserted AS i ON t.ID = i.ID;
END
GO
如果您想要 100% 万无一失地保证它们都使用相同的时间戳进行更新(尽管我不知道在这个用例中是否见过多个值):
ALTER TRIGGER [dbo].[trg_121s]
ON [dbo].[121s]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @ts DATETIME;
SET @ts = CURRENT_TIMESTAMP;
UPDATE t SET modified = @ts
FROM dbo.[121s] AS t
INNER JOIN inserted AS i
ON t.ID = i.ID;
END
GO
foo
如果您想确保仅在列更改值时才发生更新,您可以说:
UPDATE t SET modified = @ts
FROM dbo.[121s] AS t
INNER JOIN inserted AS i
ON t.ID = i.ID
AND t.foo <> i.foo;
这是一般模式,但如果它可以为空,它会变得更加复杂foo
,因为 SQL Server 将无法匹配一侧有值而另一侧没有值(或两者都没有)的行。在这种情况下,你会这样做:
AND
(
t.foo <> i.foo
OR (t.foo IS NULL AND i.foo IS NOT NULL)
OR (t.foo IS NOT NULL AND i.foo IS NULL)
);
有些人会说“我可以使用 COALESCE 或 ISNULL 来对抗一些魔法值”,如下所示:
WHERE COALESCE(t.foo, 'magic') <> COALESCE(i.foo, 'magic')
...我会警告你不要这样做,因为你会不断地寻找一些在数据中不存在的神奇值。