我已经经历了今天奇怪的问题。 我的一个项目正在运行.NET + SQL Server 2005 Express的。 有一个查询我使用一些过滤。
SELECT *
FROM [myTable]
where UI = 2011040773395012950010370
GO
SELECT *
FROM [myTable]
where UI = '2011040773395012950010370'
GO
UI列是nvarchar(256)
和UI值传递给过滤器始终是25个数字。
在我的开发环境 - 无论是查询返回相同的行和没有错误。 然而,在我的客户,运行良好的几个月后,第一个版本开始返回类型转换错误。
任何想法,为什么?
我不是在寻找的解决方案- 我在寻找解释为什么它的工作原理一个环境和其他不和为什么会出突然它开始返回错误,而不是结果 。 我使用两个(SQL Server Management Studio中Express和2个不同的.NET客户端)相同的工具
环境或多或少相同(W2K3 + SQL Server 2005 Express的)
这是完全可以预测和预期,因为数据类型优先
为此,UI栏会被转换成十进制(25,0)
where UI = 2011040773395012950010370
这一次几乎是正确的。 右手边是varchar,而改变为nvarchar
where UI = '2011040773395012950010370'
这真的是正确的版本,其中两种类型都一样
where UI = N'2011040773395012950010370'
错误会已经开始,因为UI列现在包含不会强制转换为十进制(25,0)的值。
一些不相关的注意事项:
- 如果您对UI列的索引,将在第一个版本被忽略,因为所需的隐式转换的
- 你需要统一存储位数字? 有一个严重的开销与存储和性能Unicode数据类型
- 为什么不使用
char(25)
或nchar(25)
被值总是固定长度? 您的查询使用过多存储器作为优化器基于假定的128个字符的平均长度nvarchar(256)
编辑后评论
不要以为“为什么它的工作原理有时是”当你不知道它的工作
例子:
- 该值可能已被删除,然后再加入
- TOP子句或SET ROWCOUNT可能意味着错误的值未达到
- 查询从来没有运行因此它不能失败
- 该错误是默默一些其他的代码被忽略?
编辑2的希望更加清晰
聊
摇:
当您运行WHERE UI = 2011040773395012950010370,你不知道的行访问顺序。 所以,如果一个行确实有“自行车”,你可能会或可能不会触及该行。
随机:
所以,问题可能不是排它我试图访问但损坏其他有价值的一个吗?
动摇
不同的机器都会有不同的顺序读取的基于Service Pack级别,索引和表碎片,CPU的数量,也许并行
正确
和TOP均匀。 那样的东西
陶提到 ,是要明白,另一个无关的可以打破即使这个人是OK的查询是非常重要的。
数据类型的优先级可以在该列导致所有的数据where子句被评估前被转换