由数据库排序差异引起的错误一例总结
近来在维护公司一个项目时出现一个问题:在开发阶段与QA测试阶段,奖金导入后显示均正常,但是在客户那里,导入成功后却显示为0,为何?
起初百思不得其解,直到与客户的IT人员取得联系后,通过跟踪数据库服务器的请求命令,才找到问题所在:
开发与测试数据库配置环境为:SQL SERVER 2005,语言:英文,排序:SQL_Latin1_General_CP1_CI_AS
客户数据库服务器环境配置为:SQL SERVER 2005,语言:英文,排序:Chinese_PRC_Stroke_90_CI_AS
这导致了如下面的语句:
代码
EXEC sp_executesql N'SELECT Bonus, EmpId, PayMonth, PayYear
FROM HSPayrollUploadRecord
WHERE (PayYear = @PayYear) AND (PayMonth = @PayMonth) AND (EmpId = @EmpId)',
N'@PayYear sql_variant,@PayMonth sql_variant,@EmpId sql_variant',
@PayYear = '2010', @PayMonth = '7', @EmpId = 'test02'
FROM HSPayrollUploadRecord
WHERE (PayYear = @PayYear) AND (PayMonth = @PayMonth) AND (EmpId = @EmpId)',
N'@PayYear sql_variant,@PayMonth sql_variant,@EmpId sql_variant',
@PayYear = '2010', @PayMonth = '7', @EmpId = 'test02'
在开发与测试阶段均可查询出数据,而在客户端执行后,就查询不出数据了。将此语句的参数类型修改后,问题搞定。
可是,令人疑惑的是:为什么sql_variant类型的数据参数在SQL_Latin1_General_CP1_CI_AS排序下与Chinese_PRC_Stroke_90_CI_AS排序下的值不同,这就不得而知了。
【补充】
按邹建先生的回答,答案应为:
数据类型转换导致的问题, 不是排序规则引起的问题.
第一种写法, sql_variant 的优先级最高, 所有的数据都转换为 sql_variant 后做比较, 当你的表中列类型不是 varchar 的时候, 它转换为 sql_variant 的结果与 varchar 存储到 sql_varint 中的结果不一样, 导致查不到结果
第二种写法, 你用的是基础类型, 数据转换会根据你的列和常量的数据类型判断, 是该向那种类型转换, 这种转换只要不丢失(截断)数据, 一般都能够匹配成功的.
数据类型优先级参考下面的链接