KB4058565 - 修复:在 SQL Server 2014、2016 和 2017 中执行引用大型对象的存储过程时出现断言错误

应用对象
SQL Server 2014 Enterprise - duplicate (do not use) SQL Server 2014 Enterprise Core - duplicate (do not use) SQL Server 2014 Developer - duplicate (do not use) SQL Server 2014 Standard - duplicate (do not use) SQL Server 2017 Developer on Windows SQL Server 2017 Enterprise on Windows SQL Server 2017 Enterprise Core on Windows SQL Server 2017 Standard on Windows SQL Server 2016 Service Pack 1 SQL Server 2016 Developer - duplicate (do not use) SQL Server 2016 Enterprise - duplicate (do not use) SQL Server 2016 Enterprise Core - duplicate (do not use) SQL Server 2016 Standard - duplicate (do not use)

症状

当Microsoft SQL Server重复执行执行以下操作的存储过程时,可能会出现断言错误:

  • 将大型对象(如 varchar (max) varbinary (max) )作为参数,
  • 创建一个范围限定为过程执行的临时表,以及
  • 在临时表中使用大型对象参数。

你可能会在错误日志中找到类似于以下SQL Server断言错误:

日期/时间 SPID 错误:17065,严重性:16,状态:1。

日期/时间 SPID SQL Server断言:文件:FilePath\FileName,行 = LineNumber 失败断言 = 'fFalse' 尝试访问过期的 blob 句柄 (1) 。 此错误可能与计时相关。 如果错误在重新运行语句后仍然存在,请使用 DBCC CHECKDB 检查数据库以确保结构完整性,或重启服务器以确保内存中的数据结构不会损坏。

日期/时间 SPID 错误:3624,严重性:20,状态:1。

日期/时间 SPID系统断言检查失败。 有关详细信息,请查看SQL Server错误日志。 通常,断言失败是由软件 bug 或数据损坏引起的。 若要检查数据库损坏,请考虑运行 DBCC CHECKDB。 如果你同意在安装过程中将转储发送到Microsoft,则会向Microsoft发送一个小型转储。 最新 Service Pack 中的Microsoft或技术支持提供的修补程序中可能提供了更新。

原因

SQL Server具有内部逻辑来禁用对引用大型对象的查询的缓存,以便后续执行不会引用在之前的运行期间创建的那些 LOB (,因此对于后续运行) 无效。 该逻辑未处理导致缓存这些计划的临时表上的 延迟名称解析 (DNR) 的情况。 创建作用域内临时表的成本很高,SQL Server缓存这些表,以便在后续执行中重复使用。 这可以防止由于架构更改而重新编译此类查询。

详细了解 延迟名称解析

解决方法

以下SQL Server累积更新中修复了此问题:

SQL Server 2016 SP1 的累积更新 8

2017 SQL Server累积更新 4

SQL Server 2014 Service Pack 2 的累积更新 10

关于 SQL Server 的累积更新

SQL Server 的每个新累积更新都包含先前内部版本中的所有修补程序和安全修补程序。 查看SQL Server的最新累积更新:

SQL Server 2016 年的最新累积更新

SQL Server 2017 的最新累计更新

SQL Server 2014 的最新累积更新

状态

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

参考资料

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