sql - 服务器重新启动后字符串或二进制数据被截断

标签 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),然后将其输出到嵌套循环连接操作。

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

目前,我们已经修复了通过修改表变量列的大小而损坏的几个存储过程,但我想知道是否有一种方法可以恢复统计信息和索引,以便它们生成相同的计划和以前一样,以防还有更多代码尚未执行。

最佳答案

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

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

关于sql - 服务器重新启动后字符串或二进制数据被截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19870413/

相关文章:

SQL通过大ID号连接两个表

sql-server - 在基础查询中使用 REPLACE 打开 TClientDataSet 时内存不足

sql-server - 如何使用 SSIS 包将 XML 文件加载到数据库中?

sql-server-2005 - 跨数据库的关系和约束

MySQL #1093 - 您不能在 FROM 子句中指定目标表 'giveaways' 进行更新

MySQL:如何解决此查询中的临时表错误?

mysql - SQL:了解 SELECT DISTINCT 如何消除重复项

SQL - 查询存储不一致的电话号码

sql-server - 创建和填充数字表的最佳方法是什么?

sql-server - 使用 sql_variant 有哪些陷阱?