插入和更新后未触发 SQL Server 触发器
Posted
技术标签:
【中文标题】插入和更新后未触发 SQL Server 触发器【英文标题】:SQL Server Trigger not triggered after insert and update 【发布时间】:2013-09-10 08:25:34 【问题描述】:我想将一列的内容复制到同一张表的另一列中。因此,我创建了这个触发器:
ALTER TRIGGER [dbo].[kennscht_copy_to_prodverpt]
ON [dbo].[Stammdaten]
AFTER INSERT
AS
UPDATE Stammdaten
SET PRODVERPT = (SELECT KENNSCHT FROM INSERTED)
WHERE SNR = (SELECT SNR FROM INSERTED);
但是当我在表上使用 UPDATE 将 KENNSCHT
更新为不同的值时,PRODVERPT
也不会更新。现在,您可能会争辩说这是因为触发器位于AFTER INSERT
而不是AFTER UPDATE
,但是当我更改它以使其由UPDATE
和INSERT
触发时,每当我更新任何行时,我都会收到一条错误消息SQL 服务器
无法更新行,因为它会使行不唯一或更新多行(2 行)[原文如此]
这里发生了什么?要么触发器什么都不做,要么把整个表弄乱了,使它无法更新。
更新:我还尝试了以下触发器:
UPDATE s
SET s.PRODVERPT = i.KENNSCHT
FROM Stammdaten s
INNER JOIN INSERTED i ON i.SNR = s.SNR;
但它具有完全相同的行为。如果我只使用AFTER INSERT
,没有任何变化,如果我使用AFTER INSERT, UPDATE
,我会收到上面的错误消息。
更新2:表格中没有多行,我已经检查过了,因为我认为它可能与问题有关。
【问题讨论】:
您的触发器已损坏 - 它假定inserted
仅包含一行。最好切换到FROM
/JOIN
更新样式,这样您就可以将JOIN
与inserted
一起使用,但这似乎不是这里的only 问题,因为如果它导致您出现问题,则错误消息将是关于返回多个值的子查询。
我也尝试了 JOIN - 但效果相同。一旦我使用“UPDATE”作为触发器,它就会给我错误消息。
还将SET NOCOUNT ON;
添加到触发器中。
@MartinSmith 解决了它。我现在可以运行 JOIN 触发器。谢谢!您可以将其设置为答案吗?
@FlorianPeschka - SET NOCOUNT ON
也包含在 TToni 的答案中。另外,如果有人启用了递归触发器数据库选项,这会给您带来工作的好处!
【参考方案1】:
如果您将此触发器作为AFTER UPDATE
触发器运行,它会递归运行,因为它总是针对同一个表发出另一个 UPDATE 语句,这会导致触发器的另一个执行。
要解决此问题,您需要将更新触发器设置为INSTEAD OF UPDATE
触发器,或者测试KENNSCHT
列是否已被修改。对于后者,您可以像这样使用UPDATE()
函数:
ALTER TRIGGER [dbo].[kennscht_copy_to_prodverpt_after_update]
ON [dbo].[Stammdaten]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON
IF (UPDATE(KENNSCHT))
BEGIN
UPDATE s
SET s.PRODVERPT = i.KENNSCHT
FROM Stammdaten s
INNER JOIN INSERTED i ON i.SNR = s.SNR
END
END
【讨论】:
默认情况下不启用递归触发器,如果这是问题所在,他们将收到超出递归限制的错误。问题中提到的错误是NOCOUNT ON
未打开时来自客户端工具的错误。
我一步一步尝试了这个,但是当我在触发器中设置NOCOUNT ON
之后,它已经工作了。
@Florian Pescka:我仍然认为使用我的代码是个好主意。它只在需要时发布另一个更新(并非总是像原始代码那样),并且它更加健壮,因为如果启用递归触发器,它仍然可以工作。
@Martin Smith:感谢您的提醒!我会让答案与这条评论一致,它已经被投票了,我会再为它添加一个 +1。
是的,我仍然使用你的建议,我只是想指出实际的错误是 NOCOUNT。以上是关于插入和更新后未触发 SQL Server 触发器的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL Server 2008 上创建插入更新触发器
sql server 数据库里设置了当插入数据时,便触发器插入更新时间,但我导入数据时,触发器却没有工作。