是什么原因导致sql转换日期被错误地转换?

时间:2015-10-20 08:20:10

标签: c# sql sql-server datetime

我正在使用以下代码:

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);

stimeetime都是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';

在调试器中显示时(stimeetime有一些其他选项如何设置,这就是sql动态接收它们的原因,但在当前情况下,上述情况属实)

现在当我运行上面的SQL时,我甚至从当天开始收到所有内容! 但是,当我将AS DATE更改为AS DATETIME时,它按预期工作,我刚刚获得最后一天,而今天没有任何内容。

现在我的问题是:原始sql / date比较失败有什么理由吗? (可能是因为它直到第二天它只是毫秒-1?或者还有其他原因吗?)

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'舍入,因为999997000包围。 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?