4

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

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

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

在返回错误的服务器上,改为对基表进行散列连接和表扫描。我已经尝试重建索引并更新所有涉及的表的统计信息,包括使用全扫描,并使用与工作服务器中相同的 stat_stream,但我无法恢复相同的计划。

现在我们已经修复了通过修改表变量列的大小而损坏的少数存储过程,但我想知道是否有办法恢复统计信息和索引,以便它们产生与以前相同的计划,以防有更多代码尚未执行。

4

1 回答 1

1

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

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

于 2013-11-09T00:00:38.390 回答