首页 > 解决方案 > 当我一次又一次地用相同的值更新表时会发生什么?

问题描述

当我一次又一次地用相同的值更新表时会发生什么?前任 :

更新 tblExample 设置 Col1 =1214 其中 Id=17

假设我在不更改任何列的情况下继续使用相同的值更新此记录。执行将如何发生?当我们在更新后触发器中执行此操作时会发生什么?

标签: sqlsql-serverdatabasetriggersupdates

解决方案


如果您运行一个UPDATE语句,该UPDATE语句将运行(惊喜),即使您设置列的值是相同的值。例如:

CREATE TABLE dbo.test (ID int, SomeString varchar(10));

INSERT INTO dbo.test
VALUES(1,'abc'),
      (2,'def');
GO
--Will return 1 row updated
UPDATE dbo.test
SET SomeString = 'abc'
WHERE ID = 1;
GO
--Will return 1 row updated
UPDATE dbo.test
SET SomeString = 'abc'
WHERE ID = 1;
GO

当您运行这些UPDATE语句时,SomeString仍会设置 的值。因此,如果您UPDATE在该表上有一个触发器,它仍然会触发,并执行它通常会执行的任何操作。如果您不希望这样做,则需要检查其中列的值inserteddeleted查看它是否不同。

为了进一步扩展,这里有一个带触发器的小演示(请注意,通常在SELECT触发器中有一个返回数据集的语句是不好的,并且(如果我没记错的话)是 SQL Server 2017 中已弃用的功能)。

CREATE TRIGGER dbo.test_trg ON dbo.test
AFTER UPDATE AS

    SELECT *
    FROM inserted; --SELECTs in triggers are bad!

GO
--Will perform the SELECT in the trigger
UPDATE dbo.test
SET SomeString = 'abc'
WHERE ID = 1;
GO
--Instead, check is the value is different
ALTER TRIGGER dbo.test_trg ON dbo.test
AFTER UPDATE AS

    SELECT i.*
    FROM inserted i
         JOIN deleted d ON i.ID = d.ID
    WHERE i.SomeString != d.SomeString; --SELECTs in triggers are bad!

GO
--Won't return any rows
UPDATE dbo.test
SET SomeString = 'abc'
WHERE ID = 1;
--Will return a row
UPDATE dbo.test
SET SomeString = 'bcd'
WHERE ID = 1;
GO
--Cleanup
DROP TABLE dbo.test;

推荐阅读