SQL Server 触发器 - 一个失败一个没有
Posted
技术标签:
【中文标题】SQL Server 触发器 - 一个失败一个没有【英文标题】:SQL Server triggers - one fails one doesn't 【发布时间】:2011-08-17 15:27:38 【问题描述】:我们有一个为一组大约 40 个表动态生成的触发器。考虑到触发器在表A
上的情况,它以两种方式修改表B
:
-
在表
B
中的现有行上设置脏标志
在表B
中插入任何缺失的行
两个表之间有一个链接,这样A
.bID
是B
.id
的外键。
本周我们发现,在至少一个表上,触发器未能执行第 2 步(我们不确定它是否执行第 1 步)。但它似乎适用于大多数其他表。
一时兴起,我们的一位开发人员将触发器更改为“更高效”。但后来问题似乎消失了......
我们不太清楚这两个触发器之间有什么不同,有什么见解吗?
损坏的触发器:
CREATE TRIGGER [A_Dirty] ON [A] AFTER INSERT, UPDATE, DELETE
BEGIN
SET NOCOUNT ON;
UPDATE [B] SET [timeDirty] = GETUTCDATE() WHERE [id] IN (SELECT [bID] FROM inserted);
UPDATE [B] SET [timeDirty] = GETUTCDATE() WHERE [id] IN (SELECT [bID] FROM deleted);
INSERT INTO [B] ([id], [timeDirty])
SELECT DISTINCT [bID], GETUTCDATE() FROM inserted
WHERE [bID] NOT IN (SELECT [id] FROM [B])
END
工作触发器:
CREATE TRIGGER [A_Dirty] ON [A] AFTER INSERT, UPDATE, DELETE
BEGIN
SET NOCOUNT ON;
UPDATE [B] SET [timeDirty] = GETUTCDATE() FROM inserted WHERE [id] = [bID];
UPDATE [B] SET [timeDirty] = GETUTCDATE() FROM deleted WHERE [id] = [bID];
INSERT INTO [B] ([id], [timeDirty])
SELECT DISTINCT [bID], GETUTCDATE()
FROM inserted
LEFT OUTER JOIN [B]
ON [B].[id] = inserted.[bID]
WHERE [B].[id] IS NULL
END
【问题讨论】:
第一个查询使用[B].id
,第二个 - [B].guid
用于加入。是不是印错了?
抱歉,这是一个印刷错误。我已经在问题中更正了。
【参考方案1】:
[B] 中的 [id] 是否有 NULL 值?如果是这样,NOT IN
将无法正常工作。您需要更新到以下内容:
INSERT INTO [B] ([id], [timeDirty])
SELECT DISTINCT [bID], GETUTCDATE() FROM inserted
WHERE [bID] NOT IN (SELECT [id] FROM [B] WHERE [id] IS NOT NULL)
【讨论】:
[id] 字段不可为 NULL,因此不存在 NULL 值。以上是关于SQL Server 触发器 - 一个失败一个没有的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server INSTEAD OF INSERT 触发器失败
SQL Server 禁用所有触发器 - 找不到对象“XXXX”,因为它不存在或您没有权限
SQL Server 在触发器中引发错误“触发器中的事务注定要失败。批处理已中止。”