服务器重启后截断的字符串或二进制数据

时间:2013-11-08 23:35:22

标签: sql sql-server sql-server-2005

重新启动SQL Server 2005 Standard 9.0.3233之后,我们在一些存储过程中遇到了上述错误,这些过程试图从表的特定列插入表变量。基表的列定义为varchar(10),但是表变量将列插入到仅定义为varchar(3)的列中。但是,SELECT语句仅返回3个或更少字符的数据。

我们没有以任何其他方式更改数据或代码库,这只发生在我们的生产服务器上。如果我在安装了相同SQL Server 2005版本的测试服务器上运行相同的查询,但是较旧的备份,则不会发生错误。如果删除INSERT,则会在两个查询中返回相同的数据,或者扩展表变量列以匹配基表。

我注意到,当在两台服务器上运行相同的查询时,执行计划是不同的。在查询工作的服务器上,有一个计算的标量操作,它接受列并进行隐式转换为varchar(3),然后输出到嵌套循环连接操作。

在返回错误的服务器上,存在基表的散列连接和表扫描。我已经尝试重建索引并更新所有涉及的表的统计信息,包括使用fullscan,并使用与服务器相同的stat_stream,但我无法获得相同的计划。

现在我们修改了一些通过修改表变量列大小而破坏的存储过程,但我想知道是否有办法获取统计信息和索引以便它们生成相同的计划和以前一样,如果有更多的代码还没有执行。

1 个答案:

答案 0 :(得分:1)

这是已知的行为,可能与您的重启无关。实际上,正在发生的事情是优化器出于性能原因重新排序查询的逻辑元素,但这导致在 WHERE子句的过滤之前完成截断错误检查。

建议的解决方案是将CASE..中分配给VARCHAR(3)的列表达式包装起来,复制WHERE子句中的长度测试。我知道这听起来不合逻辑,但通常会解决问题。