我在SQL Server 2005中使用datetime字段遇到了一个奇怪的错误。datetime字段以毫秒级的精度显示,但看起来并不总是使用毫秒。这是我的测试查询:
SELECT col1, YEAR(col1) AS yr, MONTH(col1) AS mn, DAY(col1) AS dy FROM mytable WHERE col1 >= '2009-12-31 00:00:00.0' AND col1 <= '2009-12-31 23:59:59.999' ORDER BY col1
在我的结果中,我得到:
col1 | yr | mn | dy ---------------------------- + ------ + ---- + ---- 2009-12-31 00:00:00:00.000 | 2009 | 12 | 31 2010-01-01 00:00:00:00.000 | 2010 | 1 | 1个
问题是我的日期是2010年1月1日,即使该日期不能小于或等于“ 2009-12-31 23:59:59.999”。但是,如果我将查询更改为使用“ 2009-12-31 23:59:59.99 8 ”,则它可以正常运行(不返回2010日期时间)。
这是Bug,还是SQL Server的工作方式?如果这是它的工作方式,那么有什么理由吗?我遇到了从MySQL迁移一些查询的问题,该查询可以按预期运行(即使MySQL甚至不存储毫秒!)。
SQL Server将时间部分存储为1/300从午夜起的第二个长滴答声的数量。
SQL Server
1/300
23:59:59.999将四舍五入到00:00:00.000第二天的最接近刻度。
23:59:59.999
00:00:00.000
SELECT CAST(CAST('2009-12-01 00:00:00.000' AS DATETIME) AS BINARY(8)), CAST(CAST('2009-12-01 23:59:59.997' AS DATETIME) AS BINARY(8)), CAST(CAST('2009-12-01 23:59:59.999' AS DATETIME) AS BINARY(8)) 0x00009B8F 00000000 0x00009B8F 018B81FF 0x00009B90 00000000
在第一个值中,日期部分0x9B8F(39823)是自以来的天数,Jan 1st, 1900时间部分0是自午夜以来的滴答数。
0x9B8F
39823
Jan 1st, 1900
0
在第二个值中,0x018B81FF(25919999或24 * 60 * 60 * 300 - 1)是自午夜以来的最大滴答数。
0x018B81FF
25919999
24 * 60 * 60 * 300 - 1
最后,第三个值0在时间部分和日期部分增加了一个。