SQL Server DateTime参数'舍入'警告 [英] SQL Server DateTime parameter 'rounding' warning

查看:115
本文介绍了SQL Server DateTime参数'舍入'警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更多的警告不是一个问题:

More of a warning than a question:

我们今天早上解决了一个非常令人困惑的错误。我们有各种各样的报告,允许用户输入他们想要运行的日期范围。假设是,如果您要求2010年8月8日至2010年8月8日的报告,您意味着包括 8/10/2010,所以报告的结束日期不是8 / 10,这是之后的事情。

We resolved a very puzzling bug this morning. We have a variety of reports that allow users to enter date ranges they want to run. The assumption is, if you ask for a report from 8/1/2010 to 8/10/2010 you meant to include 8/10/2010 so the end-date of the report isn't 8/10, it's something after that.

它不能是8/11/2010因为这些报告中的一些汇总了一天中发生的一切,在当天将其分组这是在午夜,所以每天的汇总将包括一个额外的一天 - 不是我们想要的。

It can't be 8/11/2010 becuase some of these reports rollup everything that happened during a day grouping them by that day which is at midnight, so a daily rollup would include an extra day - not what we wanted.

为了避免错过任何非常接近尾声的项目的可能性当天,我们将结束日期计算为明天的一滴:

To avoid the possibility of missing any items very very close to the end of the day, we computed the end date as 'one tick' less than tomorrow:

public static DateTime EndOfDay(DateTime day)
{
    return day.Date.AddDays(1).AddTicks(-1);
}

内部这样做会像8/10/2010 12:59:59.9999 PM

Internally this ends up something like 8/10/2010 12:59:59.9999PM

当您将此DateTime传递给SQL Server中的DATETIME参数时,将值UP到8/11/2010 00:00:00!而且由于我们的查询使用

Well, when you pass this DateTime to a DATETIME parameter in SQL Server it rounds the value UP to 8/11/2010 00:00:00! And since our query uses

DateField BETWEEN @FromDate AND @ToDate

而不是

DateField >= @FromDate AND DateField < @ToDate

我们看到8/1 / 2010-8 / 10/2010的报告包括8/11/2010。

We were seeing reports from 8/1/2010-8/10/2010 include items from 8/11/2010.

我们发现真正问题的唯一方法是通过一个字符串的日期。 DateTime.ToString()也是圆的,所以我们最终会遇到SQL Server很满意的8/1/2010 12:59:59 PM。

The only way we discovered the real problem was by round-tripping the dates thru a string. DateTime.ToString() rounds too so we'd end up with 8/1/2010 12:59:59PM which SQL Server was happy with.

所以现在我们的'结束日期方法如下所示:

So now our 'end of day' method looks like this:

public static DateTime EndOfDay(DateTime day)
{
    // Cant' subtract anything smaller (like a tick) because SQL Server rounds UP! Nice, eh?
    return day.Date.AddDays(1).AddSeconds(-1);
}

对不起没有问题 - 只是想有人可能会发现它很有用。 >

Sorry not a question - just thought someone might find it useful.

推荐答案

这是因为DATETIME数据类型的准确性,具有准确性( quote ):

It's because of the accuracy of the DATETIME datatype, which has an accuracy (quote):


舍入为0.000,.003,
或.007秒的增量

Rounded to increments of .000, .003, or .007 seconds

所以是的,你做必须在某些情况下小心(例如23:59:59.999将被舍入到第二天的00:00,23:59:59.998将被舍入到23:59:59.997)

So yes you do have to be careful in certain situations (e.g. 23:59:59.999 will be rounded up to 00:00 of the following day, 23:59:59.998 will be rounded down to 23:59:59.997)

SELECT CAST('2010-08-27T23:59:59.997' AS DATETIME)
SELECT CAST('2010-08-27T23:59:59.998' AS DATETIME)
SELECT CAST('2010-08-27T23:59:59.999' AS DATETIME)

从SQL Server 2008起,有一个新的 DATETIME2 数据类型,其精度可达100纳秒。

As of SQL Server 2008, there is a new DATETIME2 datatype which gives greater accuracy down to 100 nanoseconds.

当我在DATETIME字段包含一个时间元素,因此不使用BETWEEN。

When I'm doing queries on a DATETIME field which contains a time element, I don't use BETWEEN for this reason.

eg我更喜欢

WHERE DateField >= '2010-08-27' AND DateField < '2010-08-28'

而不是:

WHERE DateField BETWEEN '2010-08-27' AND '2010-08-27T23:59:59.997'

这篇关于SQL Server DateTime参数'舍入'警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆