我有两个几乎相同的SELECT语句.我在SQL Server 2012上使用服务器排序规则Danish_Norwegian_CI_AS和数据库排序规则Danish_Norwegian_CI_AS运行它们.数据库以设置为SQL Server 2005(90)的兼容级别运行.
我通过SQL Server 2012 Management Studio在同一客户端上运行这两个查询.客户端是Windows 8.1笔记本电脑.
令人费解的是,尽管语句几乎相同,但结果集不同,如下所示(一个返回24小时格式时间,另一个返回AM / PM,在这种情况下会截断tpo P).唯一的区别是WHERE子句中的’和1<> 2’表达式.我上下打量,在谷歌搜索,尽可能深地挖掘,找不到解释.尝试COLLATE强制转换,没有帮助.如果我使用108强制CONVERT调用格式化,那么结果集是相似的.但不知道为什么这不起作用的原因是让我活着.
在SqlFiddle,SQL Server 2008上重新创建的问题:
http://sqlfiddle.com/#!3/a97f8/1
有人为此解释一下吗?
结果之后的SQL DDL和语句可用于重新创建问题.该脚本创建一个包含两列的表,插入一些行,并进行两次选择.
在我的机器上,没有1<> 2表达式的sql返回:
Id StartTime
----------- ---------
2 2:00P
2 2:14P
具有1<> 2表达式的sql返回:
Id StartTime
----------- ---------
2 14:00
2 14:14
if NOT EXISTS (Select * from sysobjects where name = 'timeVarchar')
begin
create table timeVarchar (
Id int not null,
timeTest datetime not null
)
end
if not exists (select * from timeVarchar)
begin
-- delete from timeVarchar
print 'inserting'
insert into timeVarchar (Id, timeTest) values (1, '2014-04-09 11:37:00')
insert into timeVarchar (Id, timeTest) values (2, '1901-01-01 14:00:00')
insert into timeVarchar (Id, timeTest) values (3, '2014-04-05 15:00:00')
insert into timeVarchar (Id, timeTest) values (2, '1901-01-01 14:14:14')
end
select
Id,
convert ( varchar(5), convert ( time, timeTest)) as 'StartTime'
from
timeVarchar
where
Id = 2
select
Id,
convert ( varchar(5), convert ( time, timeTest)) as 'StartTime'
from
timeVarchar
where
Id = 2 and
1 <> 2
最佳答案 我无法回答为什么会发生这种情况(至少目前还没有),但明确设置转换格式确实解决了这个问题:
select Id,
convert (varchar(5), convert (time, timeTest), 14) as "StartTime"
from timeVarchar
where Id = 2;
select Id,
convert (varchar(5), convert (time, timeTest), 14) as "StartTime"
from timeVarchar
where Id = 2
and 1 <> 2;
通过执行计划,这两个查询的结果确实非常不同.
第一个传递2作为参数,(!)传递值为CONVERT_IMPLICIT.第二个将它作为查询本身的一部分传递给它!
最后,在第一种情况下运行的实际查询实际上显式地执行CONVERT(x,y,0).对于美国语言环境,这不是问题,因为0是不变(~US)文化.但是在美国之外,你突然使用0而不是4(德国).
所以,当然,有一点需要考虑的是,看起来非常相似的查询可以完全不同地执行.
第二件事是 – 始终使用特定格式的转换.默认值似乎并不完全可靠.
编辑:啊,最后从MSDN中捕获的东西:
http://msdn.microsoft.com/en-us/library/ms187928.aspx
In earlier versions of SQL Server, the default style for CAST and
CONVERT operations on time and datetime2 data types is 121 except when
either type is used in a computed column expression. For computed
columns, the default style is 0. This behavior impacts computed
columns when they are created, used in queries involving
auto-parameterization, or used in constraint definitions.
由于第一个查询是作为参数化查询调用的,因此它获取默认样式0而不是121.此行为在兼容级别110(即SQL SERVER 2012)中得到修复 – 在这些服务器上,默认值始终为121.