批量更新时SQL Server的UPDATE()函数与触发器工作机制咨询
SQL Server触发器相关问题解答
问题背景
SQL Server触发器针对批处理执行,而非事务中的单一行数据。若单个事务内更新了表的N行数据,UPDATE触发器会将这N行作为整体进行处理。
给定表结构:
CREATE TABLE [dbo].[Sample]( SampleId INT IDENTITY(1,1) NOT NULL, Column1 VARCHAR(100) NULL, CONSTRAINT [PK_Sample] PRIMARY KEY CLUSTERED (SampleId ASC) );
执行更新语句:
UPDATE Sample SET Column1 = 'Example' WHERE SampleId <= 5;
触发器中包含条件:IF UPDATE(Column1)
问题1
IF UPDATE(Column1)是在所有N行的Column1都被更新时才判定为真,还是只要任意一行的Column1被更新就判定为真?
解答:只要本次批处理的更新操作中,有任意一行的Column1被指定为更新目标(哪怕实际值未发生变化),UPDATE(Column1)就会返回真。比如你执行的UPDATE Sample SET Column1 = 'Example' WHERE SampleId <=5,只要语句明确指定更新Column1,不管这5行的Column1原值是否为'Example',触发器里的UPDATE(Column1)都会判定为真。
问题2
是否存在逐行判断该条件的方法?
解答:无法直接用UPDATE()函数实现逐行判断,但可以通过触发器自带的inserted和deleted临时表对比,逐行检查Column1是否真的发生变化:
deleted表存储更新前的行数据inserted表存储更新后的行数据
示例代码如下:
SELECT SampleId, CASE WHEN deleted.Column1 <> inserted.Column1 THEN '已更新' ELSE '未更新' END AS Column1_Update_Status FROM inserted JOIN deleted ON inserted.SampleId = deleted.SampleId;
若Column1允许为NULL,需补充NULL值对比逻辑:
SELECT SampleId, CASE WHEN ISNULL(deleted.Column1, '') <> ISNULL(inserted.Column1, '') THEN '已更新' ELSE '未更新' END AS Column1_Update_Status FROM inserted JOIN deleted ON inserted.SampleId = deleted.SampleId;
补充问题
若在单个事务中对同一表执行两次不同的更新操作,UPDATE触发器会针对每条UPDATE语句触发一次,还是针对整个事务仅触发一次?
解答:触发器会针对每条UPDATE语句触发一次。即使两次更新处于同一事务中,触发器也会被触发两次,每次触发处理对应UPDATE语句影响的行集合。
内容的提问来源于stack exchange,提问作者Nayak S
相关产品推荐
相关产品推荐

