SQL Server 2008查询指定日期起记录结果不一致问题咨询
为什么两种日期查询写法返回的记录数不同?
这个问题我之前排查过,核心原因是SQL Server对日期字符串的解析逻辑在两种写法下存在差异,尤其是依赖的系统设置不一样:
写法一:
SELECT * FROM MyTable WHERE DateTimeField >= '20101201'
这里的'20101201'是无分隔符的数字日期格式(yyyymmdd),这是SQL Server官方认定的「安全日期格式」——不管你的数据库服务器的语言、区域设置或者DATEFORMAT参数是什么,这个格式都会被准确解析为2010-12-01 00:00:00.000,所以查询条件是严格匹配“大于等于2010年12月1日零点”的记录。写法二:
SELECT * FROM MyTable WHERE DateTimeField >= Convert(datetime, '2010-12-01')
这个写法用了显式转换,但没有指定style参数,这时候SQL Server会根据当前会话的**DATEFORMAT设置**来解析字符串'2010-12-01'。举个例子:- 如果你的服务器默认语言是
us_english,DATEFORMAT是mdy(月/日/年),'2010-12-01'会被解析为2010年12月1日(和预期一致); - 但如果服务器语言是
British或者French,DATEFORMAT是dmy(日/月/年),这时候'2010-12-01'会被错误解析为**2010年1月12日**(因为把12当成日,01当成月)。
这时候查询条件变成了“大于等于2010年1月12日”,自然会返回更多记录,和写法一的结果数量就不一样了。
- 如果你的服务器默认语言是
怎么解决这个问题?
你可以用以下几种方法确保日期解析的准确性:
- 继续使用无分隔符的数字格式,比如
'20101201',这种写法最稳妥,不需要担心设置影响; - 在
CONVERT时指定明确的style参数,比如:
这里的SELECT * FROM MyTable WHERE DateTimeField >= Convert(datetime, '2010-12-01', 23)23对应yyyy-mm-dd格式,不管系统设置如何,都会正确解析; - 使用SQL Server 2008及以上支持的
DATEFROMPARTS函数,直接构造日期:
这种写法可读性最高,也完全不会有解析歧义。SELECT * FROM MyTable WHERE DateTimeField >= DATEFROMPARTS(2010, 12, 1)
内容的提问来源于stack exchange,提问作者Willy
相关产品推荐
相关产品推荐

