批量更新数据小心SQL触发器的陷阱
背景交代:
后台有个发送邮件的表A,专门记录需要发送的邮件信息,job就负责取数据,发送,然后更新发送结果返回A
后台A表还有个update触发器,如果状态更改,会往B表写记录
执行更新A状态时是用了update语句的批量更新方法
出现的问题:
每次更新状态,触发器只能获取到批量更新的第一个ID值,无法获取正常记录的其他ID
百度了一下,发现原来批量更新时 update触发器只会被update触发一次,无论更新的记录数是多少
https://www.cnblogs.com/51net/p/3578323.html
解决思路:
1、最常见的一种思路 就是去掉批量更新update语句 (update table set state= 1 where ids in (xxxxxx)),改为执行proc方式,然后在proc中循环更新
2、结合游标处理 游标基础语法传送门 触发器使用游标小demo传送门
这里重点说一下结合游标的处理方式
Create TRIGGER [dbo].[tgr_test_update] ON [dbo].[EMAIL] FOR UPDATE AS begin if update([state]) --表示只有state字段被更新时 处理以下逻辑,可省去判断 BEGIN DECLARE @fID int --用游标,一个一个处理 DECLARE tmpGoods CURSOR for select request_id from inserted where ([state]=1 and len(accessory)>0) --定义游标,where条件是对inserted临时表数据的过滤,过滤后拿到主键ID OPEN tmpGoods --打开变量游标 FETCH NEXT FROM tmpGoods into @fID --取值并付给变量@fID WHILE @@FETCH_STATUS=0 --@@FETCH_STATUS 全局变量,其值为0表示上一个FETCH执行成功;为-1表示所要读取的行不在结果集中;为-2表示被提取的行已不存在(已被删除)。 BEGIN --操作语句(将符合结果都ID主键插入到检测表中) insert into temp_email values(0,'拿到了state符合条件的记录','ID值是:' + convert(nvarchar,@fID)) --实际处理业务逻辑(已经拿到满足条件的ID,可以拿ID在inserted临时表中获取其他信息) --xxxxxxx(执行其他insert语句 或者update语句) FETCH NEXT FROM tmpGoods into @fID --再次获取满足条件的@fID END CLOSE tmpGoods --关闭游标 DEALLOCATE tmpGoods --删除游标 END END

浙公网安备 33010602011771号