症状
假设您创建了一个存储过程,该存储过程在 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 2014 累积更新 13
- SQL Server 2014 Service Pack 1 (SP1 的累积更新 6)
- SQL Server 2012 Service Pack 3 (SP3 累积更新 2)
- SQL Server 2012 Service Pack 2 (SP2 的累积更新 11)
建议:安装 SQL Server 的最新累积更新
SQL Server 的每个新累积更新都包含上一个累积更新中包含的所有修补程序和所有安全修补程序。 查看 SQL Server 的最新累积更新:
- SQL Server 2014 的最新累计更新
- SQL Server 2014 SP1 的最新累计更新
- SQL Server 2012 SP2 的最新累计更新
- SQL Server 2012 SP3 的最新累计更新
状态
Microsoft 已确认在 "适用于" 部分中所列的 Microsoft 产品中存在问题。
参考资料
了解 Microsoft 用于描述软件更新的术语。