批量更新数据小心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

 

posted @ 2021-06-23 16:36  狼窝窝  阅读(705)  评论(0)    收藏  举报