KB3138930 - 修复:执行在 SQL Server 中的表变量上使用光标的存储过程时出现访问冲突

应用对象
SQL Server 2012 Service Pack 3 SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use)

症状

假设您创建了一个存储过程,该存储过程在 Microsoft SQL Server 2012 或 SQL Server 2014 中的表变量上使用游标。 此外,存储过程通过将 WHERE CURRENT OF 语句与游标一起使用来更新表。

例如,存储过程可能类似于以下内容:

CREATE PROCEDURE dbo.usp_TestSP AS 

BEGIN 

DECLARE @TableVar TABLE (SomeInt INT NULL) 
INSERT @TableVar VALUES (NULL) 

DECLARE @curInt INT, @newInt INT 
SET @newInt = 1 

DECLARE ccc CURSOR LOCAL FOR 
SELECT SomeInt FROM @TableVar WHERE SomeInt IS NULL 

OPEN ccc 

FETCH NEXT FROM ccc INTO @curInt 
UPDATE @TableVar SET SomeInt = @newInt 
WHERE CURRENT OF ccc
CLOSE ccc 

SELECT * FROM @TableVar 
END 

使用 sp_refreshsqlmodule 系统存储过程执行存储过程时,可能会发生访问冲突,并且可能会收到类似以下内容的错误消息:

注意

消息 596,级别 21,状态 1无法继续执行,因为会话处于终止状态。消息 0,级别 20,状态 0当前命令上发生严重错误。 如果有结果,应丢弃。

在这种情况下,类似以下的错误也会写入 SQL Server 错误日志:

注意

date time.730 spid51 SqlDumpExceptionHandler:处理 51 生成的致命异常 c0000005 EXCEPTION_ACCESS_VIOLATION。 SQL Server 正在终止此进程。
date time.730 spid51 * *******************************************************************************
date time.730 spid51 *
date time.730 spid51 * BEGIN STACK DUMP:
date time.730 spid51 * date time spid 51
date time.730 spid51 *
date time.730 spid51 *
date time.730 spid51 * 异常地址 = 00007FFC270236D5 模块 (sqllang+00000000005036D5)
date time.730 spid51 * 异常代码 = c0000005 EXCEPTION_ACCESS_VIOLATION
date time.730 spid51 * 读取地址 0000006F00620074 发生访问冲突
date time.730 spid51 * 输入缓冲区 136 字节 -
date time.730 spid51 * EXECUTE sp_refreshsqlmodule N'[dbo].[usp_TestSP]'
date time.730 spid51 *
date time.730 spid51 *

      

解决方法

累积更新信息

此问题已在以下更新中修复:

          

建议:安装 SQL Server 的最新累积更新

SQL Server 的每个新累积更新都包含上一个累积更新中包含的所有修补程序和所有安全修补程序。 查看 SQL Server 的最新累积更新:

      

状态

Microsoft 已确认在 "适用于" 部分中所列的 Microsoft 产品中存在问题。

参考资料

了解 Microsoft 用于描述软件更新的术语。