【发布时间】:2014-04-02 23:51:36
【问题描述】:
我有三个表,“元素”表中的行属于“项目”表中的一行,而这些行又属于“类别”表中的一行。 现在,我在每个表上都设置了触发器,以在插入或更新时更新时间戳(updatedAt):
CREATE TRIGGER [Category_InsertUpdateDelete] ON [Category]
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
IF TRIGGER_NESTLEVEL() > 3 RETURN;
UPDATE [Category] SET [Category].[updatedAt] = CONVERT (DATETIMEOFFSET(3), SYSUTCDATETIME())
FROM INSERTED
WHERE INSERTED.id = [Category].[id]
END
现在我正在尝试更新父行的时间戳:
CREATE TRIGGER [Item_InsertUpdateDelete] ON [Item]
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
IF TRIGGER_NESTLEVEL() > 3 RETURN;
DECLARE @updatedAt DATETIMEOFFSET(3) = CONVERT(DATETIMEOFFSET(3), SYSUTCDATETIME());
UPDATE [Item] SET [Item].[updatedAt] = @updatedAt
FROM INSERTED
WHERE INSERTED.id = [Item].[id]
UPDATE [Category] SET [Category].[updatedAt] = @updatedAt
FROM INSERTED
WHERE INSERTED.categoryId = [Category].[id] AND [Category].[updatedAt] < @updatedAt;
END
不过有两个问题:
1)它导致死锁,因为项目触发器似乎正在等待类别触发器,两者都想更新类别。
2) 类别 updatedAt 时间戳将与项目时间戳不同,因为类别的触发器将再次更改它(产生毫秒左右的差异)。
我虽然使用 UPDATE() 函数检查 Category 触发器中的 updatedAt 列是否已更改,但我不清楚这是否适用于批量插入/更新。是否会检查 TRIGGER_NESTLEVEL 以查找可能导致这种“级联”的特定触发器,如果它返回超过 0 个则简单地返回?
执行这种时间戳“级联”的最佳方式是什么?
提前致谢!
【问题讨论】:
标签: sql-server tsql triggers azure-sql-database