SQL存储过程持续执行无法终止,求排查原因建议
排查存储过程sp_RemovePaddingPicture_Name无限执行的建议
可能的原因分析
你的存储过程使用默认游标遍历并更新数据,SQL Server中默认游标为FORWARD_ONLY DYNAMIC类型,这类游标会实时反映基表的修改。当执行UPDATE ... WHERE CURRENT OF cur修改PICTURE_NAME字段时,可能导致游标结果集重新生成,出现重复遍历行的情况,进而引发无限循环。另外,如果表中数据量极大,也可能让你误以为是无限执行。
排查与修复步骤
修改游标类型为静态快照游标:静态游标基于查询时的数据集快照,不受后续基表更新影响,能避免循环异常。修改游标声明:
DECLARE cur CURSOR STATIC FOR SELECT Picture_Name FROM PEOPLEGENERAL验证是否为数据量过大导致的长耗时:先统计表中行数确认数据规模:
SELECT COUNT(*) FROM PEOPLEGENERAL也可以在循环内添加打印语句跟踪处理的行,判断是否重复处理同一行(需先把FETCH结果赋值给@test):
-- 调整FETCH语句并添加打印 FETCH FROM cur INTO @test WHILE @@FETCH_STATUS = 0 BEGIN PRINT '当前处理:' + @test UPDATE PEOPLEGENERAL SET PICTURE_NAME = RTRIM(PICTURE_NAME) WHERE CURRENT of cur FETCH NEXT FROM cur INTO @test END检查表锁与阻塞情况:如果存在其他事务锁定
PEOPLEGENERAL表,会导致更新操作阻塞,表现为“无限执行”。可通过以下语句查看锁状态:SELECT * FROM sys.dm_tran_locks WHERE resource_associated_entity_id = OBJECT_ID('PEOPLEGENERAL')替换游标为批量更新(推荐):游标效率低下且易出问题,直接用批量更新完成需求,避免循环风险:
UPDATE PEOPLEGENERAL SET PICTURE_NAME = RTRIM(PICTURE_NAME) WHERE PICTURE_NAME <> RTRIM(PICTURE_NAME) -- 仅更新需要修剪的行,提升效率
内容的提问来源于stack exchange,提问作者azenk
相关产品推荐
相关产品推荐

