这是保持简单跟踪数据库行更改的最佳方法:
ALTER TRIGGER [dbo].[trg_121s]
ON [dbo].[121s]
AFTER UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for trigger here
update dbo.[121s]
set modified=getdate()
where id in
(select distinct ID from Inserted)
END
因此,对[121s]中某行的任何更新都会导致更新已修改列。
它有效,但我不确定这是否是实现这一目标的最佳方法。
我对这条线路感到困惑:
(select distinct ID from Inserted)
...以及它如何知道它获得了正确的行ID。
感谢您的任何确认/澄清,
标记
答案 0 :(得分:19)
inserted
是一个伪表,它肯定包含受UPDATE
语句影响的所有正确的行(我假设DISTINCT
不是必需的,如果{{1主键 - 虽然很难用ID
之类的名称来表示表的内容。在应用修改后的日期/时间之前,您是否可以考虑验证是否所有人都实际上已经更改了值。除此之外,我可能会这样做:
121s
如果你想要100%万无一失的保证他们都使用相同的时间戳更新(虽然我不知道在这个用例中我是否见过多个值):
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);
END
GO
如果您想确保仅在列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
WHERE EXISTS (SELECT 1 FROM inserted WHERE ID = t.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;
可以为空,则会变得更加复杂,但这是一般模式。
答案 1 :(得分:2)
Inserted是一个表,其中包含受触发(插入/更新)操作影响的行。所以你的触发器是正确的。如果Id是主键,那么您不需要distinct(从Inserted中选择id就足够了)。如果Id不是主键,那么您的触发器是错误的,因为您最终可能会更新更多内容。
答案 2 :(得分:1)
虽然很多,不仅仅是在Stackoverflow上,而是在全世界都会告诉你触发器是邪恶的,我会说它们在没有被滥用的情况下保持价值。在这里,如果你想使用这个触发器,它似乎是有效的,Inserted
表包含由触发此触发器的语句更新的行 - 它是正确的,除非DISTINCT
可能被删除ID
{1}}是主键。
但是,如果您具有灵活性,另一个选项是使用timestamp
列。但是,不要混淆,timestamp
列不与日期和时间相关联。因此,如果您需要日期和时间,请坚持使用。