SQL Server 触发器在插入和更新后未触发

标签 sql sql-server t-sql triggers

我想将一列的内容复制到同一个表中的另一列中。因此,我创建了这个触发器:

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 Server 收到错误消息

Cannot update row because it would make the row not unique or update multiple rows (2 rows) [sic]

这是怎么回事?触发器要么不执行任何操作,要么弄乱了整个表,使其无法更新。

更新:我还尝试了以下触发器:

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:表中没有多行,我已经检查过,因为我认为它可能与该问题有关。

最佳答案

如果将此触发器作为 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

关于SQL Server 触发器在插入和更新后未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18713994/

相关文章:

sql-server - 将 ApplicationIntent=ReadOnly 与将数据插入临时表的存储过程一起使用

sql - 如何在 RAISERROR 方法中打印 DateTime 变量?

sql - 如何通过 HAVING 条件过滤原始行?

sql - 基于IF的SQL查询?

c# - 以编程方式将新用户插入到 aspnet 成员资格架构中

sql - 从多个表中获取总和

php - 如何检查包含字符串的列?

python - 如何强制 Postgresql 使用任何 SQL 语句为丢失的数据返回 None?

sql - 如何只比较月份和年份,而不是完整的日期?

sql - 索引可用时进行全表扫描