我正在使用以下代码:
sqlcom.CommandText = "SELECT * FROM myTable"
+ " WHERE CAST(myTime AS DATE) >= CAST(@mySTime AS DATE)"
+ " AND CAST(myTime AS DATE) <= CAST(@myETime AS DATE)"
+ "order by myTime ";
sqlcom.Parameters.AddWithValue("@mySTime", stime);
sqlcom.Parameters.AddWithValue("@myETime", etime);
stime
和etime
都是DateTime
列。以下是设置它们的代码的缩写:
sTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0).AddDays(-1);
eTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0).AddDays(-1).AddDays(1).AddMilliseconds(-1);
例如导致:
sTime = '2015-10-19 00:00:00';
eTime = '2015-10-19 23:59:59';
在调试器中显示时(stime
和etime
有一些其他选项如何设置,这就是sql动态接收它们的原因,但在当前情况下,上述情况属实)
现在当我运行上面的SQL时,我甚至从当天开始收到所有内容!
但是,当我将AS DATE
更改为AS DATETIME
时,它按预期工作,我刚刚获得最后一天,而今天没有任何内容。
现在我的问题是:原始sql / date比较失败有什么理由吗? (可能是因为它直到第二天它只是毫秒-1?或者还有其他原因吗?)
答案 0 :(得分:4)
eTime = new DateTime(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,0,0,0).AddDays(-1).AddDays(1).AddMilliseconds(-1);
您为什么使用.AddDays(-1).AddDays(1)
。这似乎毫无用处。
.AddMilliseconds(-1)
您的数据类型为日期时间。 日期时间的准确度为3毫秒,增量为.000,003或.007秒。 因此,这3个值中的任何一个减去1(ms)总是回归到原始值:
xxx.000 - .001 = .999 => rounded to .000
xxx.003 - .001 = .002 => rounded to .003
xxx.007 - .001 = .006 => rounded to .007
这似乎也没用。
总结
'2015-10-19 23:59:59'
不会被舍入,但'2015-10-19 23:59:59.999'
将向'2015-10-20 00:00:00.000'
舍入,因为999
被997
和000
包围。 000
是最接近的值。
<= 18-10-2015 23:59:59
您将错过23:59:59.000
及以下等于23:59:59.997
CAST(myTime AS DATE)
这很可能会阻止在myTime上使用索引。不应该使用它。
坚持datetime是好的,尽管datetime2会是更好的选择。如果您在特定日期寻找价值,您必须在DAY 00:00:00和第二天00:00:00之间寻找价值。
您可以在此处找到大量有关日期比较的有用信息,包括我自己的答案:Why does my query search datetime not match?