SQL Query不会选择日期范围启动

时间:2014-08-03 20:21:55

标签: sql date sql-server-2008-r2

  • SQL Server 2008 R2
  • VB.net
  • Silverlight 5

数据库是没有时间组件的日期类型。在查询中,我放置了一个时间组件来确保正确的开始和结束时间。如果我将开始日期调整为UTZ时间,则查询有效。如果我在午夜之前将开始日期调整为昨天1秒,则不起作用。这向我表明数据库将日期存储为UTZ但似乎不可能。

我有这个:

  • ID AS int
  • dt AS Date

表中有2行:

ID  dt
------------
1   8/1/2014
2   8/2/2014

PARAMS:

  • &FromDate = "8/1/2014 00:00:00"
  • &ToDate = "8/2/2014 23:59:59"

查询:

SELECT * 
FROM Table 
WHERE dt >= &FromDate AND dt <= @ToDate

结果:

ID  dt
------------    
2   8/2/2014

日期列在表格中:

为MyObject

dt as date

myObject.dt = "8/1/2014"

@dt = myObject.dt

INSERT INTO Table (dt) VALUES (@dt)

为什么我没有使用此查询获取两个记录?我该如何解决?

这有效:

FromDate = Format(FromDate, "MM/dd/yyyy 00:00:00.000"):FromDate = FromDate.AddHours(-5)

ToDate = Format(ToDate.AddDays(1), "MM/dd/yyyy 00:00:00.000"):ToDate = ToDate.AddHours(-5)

sb.Append("AND s.AlarmDate>=@FromDate AND s.AlarmDate<@ToDate ")

更新:

详细解释环境和问题。

我已经通过调整指示的日期解决了这个问题,但我不喜欢这个解决方案而且我不明白导致问题的原因。

环境:

开发服务器是带有SQL Server 2008 R2的Windows 2003 Server。服务器时区是CDT。 生产服务器是Windows Server 2008,也运行SQL Server 208 R2,时区CDT。 开发和生产服务器都表现出与此问题相同的行为。

项目是Silverlight 5网站。

客户端计算机是Windows XP,时区设置为CDT。

要将包含日期的记录存储在数据库中,用户启动一个对话框,该对话框创建一个带有日期属性的数据对象,该数据对象绑定到一个日期选择器。

让我们假设用户选择日期为8/1/2014。

当用户单击“保存”按钮时,对象将被预先序列化为xml,以便发布到服务器上托管的Web服务,以便存储在数据库中。

序列化过程在xml中放置一个时间戳,以便到达服务器的xml具有:

2014-08-01T00:00:00

当webservice收到这个xml时,它会被反序列化为我的数据对象,如下所示:

Dim oNote As New DataNote
Dim ser As New XmlSerializer(oNote.GetType)
Dim myStream As New System.IO.MemoryStream(New System.Text.UnicodeEncoding().GetBytes(xml))
oNote = ser.Deserialize(myStream)
myStream.Close()

将xml反序列化到我的对象后,我重新分配了删除时间戳的日期。我这样做是为了尽早解决问题,通过使用字符串操作并删除时间戳并仅将日期部分(作为字符串)分配给我的对象属性我确保如果有时间组件则将其设置为午夜。这一步可能是不必要的。

接收日期的数据对象属性是日期类型,而不是日期时间,sql表字段和更新数据库的存储过程的参数也是如此。

从客户端或开发计算机使用SQL Server Management Studio检查数据库,在数据库中显示日期为“2014-08-01”。

到目前为止一切顺利。

查询日期并显示问题:

我正在使用telerik报告,它托管一个objectdatasouce,它使用我编写的类返回我的对象​​列表。此代码在服务器端运行。数据类使用ASP.NET提供的SqlConnection,我假设它是ADO来打开和查询数据库。

使用此子句查询日期范围时,查询是非常向前的。

“s.AlarmDate&gt; = @ FromDate AND s.AlarmDate&lt; = @ ToDate”

如果我使用#8/1/2014#的FromDate,则查询找不到记录。经过实验,我发现我必须从FromDate中减去5个小时才能返回记录。

这意味着数据库的行为就好像数据库中的数据是'7/31/2014 19:00:00“。这是从'实际'日期开始的-5小时,恰好是UTZ偏移量CDT(中部夏令时)。

这也可能意味着我的FromDate提前5个小时。这对我来说意义不大,所以我不予理睬。

就是这样。没有涉及其他层,它就这么简单。

3 个答案:

答案 0 :(得分:1)

尝试将代码更改为:

&FromDate = "8/1/2014 00:00:00"
&ToDate = "8/3/2014 00:00:00"

SELECT * 
FROM Table 
WHERE dt >= &FromDate AND dt < @ToDate

请注意不等式和ToDate值的非常重要的变化。 SQL Server中存在一个问题,即在一小时之前和之后的时间分辨率,需要使用此技术来获得正确的可重现结果。实际上,在日期更改之前,无法可靠地将日期时间值设置为

此外,强烈建议您使用格式'yyyymmdd'将日期字符串隐式转换为日期(或dtetimes),或明确选择特定格式using the CONVERT function

更新 - 来自上述OP的评论。

始终将最具体的数据类型用于存储过程的参数。将存储过程中date参数的数据类型更改为DATE,以便您可以控制到/从字符的转换。

答案 1 :(得分:0)

我的猜测是它是8/2日期行的时间成分。

例如,如果是:

insert into tbl values (2, '08/02/2014 23:59:59.999');

该行不会在您的查询中返回(请注意.999) 小提琴:http://sqlfiddle.com/#!3/6dc42/1/0

但如果该行是:

insert into tbl values (2, '08/02/2014 23:59:59');

那一排会回来(没有.999) - 小提琴:http://sqlfiddle.com/#!3/ed49b/1/0

尝试将参数更改为以下值(使用nnn秒):

select *
from tbl 
where dt >= '8/1/2014 00:00:00' and dt <= '8/2/2014 23:59:59.999'

小提琴:http://sqlfiddle.com/#!3/6dc42/3/0

请参阅http://msdn.microsoft.com/en-us/library/ms186724.aspx

或者,如果您可以将条件更改为小于&#39;而不是&lt; =你可以做&lt;第三个是0小时。

答案 2 :(得分:0)

不是答案,而是对环境和问题的详细解释。

我已经通过调整指示的日期解决了这个问题,但我不喜欢这个解决方案而且我不明白导致问题的原因。

环境:

开发服务器是带有SQL Server 2008 R2的Windows 2003 Server。服务器时区是CDT。 生产服务器是Windows Server 2008,也运行SQL Server 208 R2,时区CDT。 开发和生产服务器都表现出与此问题相同的行为。

项目是Silverlight 5网站。

客户端计算机是Windows XP,时区设置为CDT。

要将包含日期的记录存储在数据库中,用户启动一个对话框,该对话框创建一个带有日期属性的数据对象,该数据对象绑定到一个日期选择器。

让我们假设用户选择日期为8/1/2014。

当用户单击“保存”按钮时,对象将被预先序列化为xml,以便发布到服务器上托管的Web服务,以便存储在数据库中。

序列化过程在xml中放置一个时间戳,以便到达服务器的xml具有:

2014-08-01T00:00:00

当webservice收到这个xml时,它会被反序列化为我的数据对象,如下所示:

Dim oNote As New DataNote
Dim ser As New XmlSerializer(oNote.GetType)
Dim myStream As New System.IO.MemoryStream(New System.Text.UnicodeEncoding().GetBytes(xml))
oNote = ser.Deserialize(myStream)
myStream.Close()

将xml反序列化到我的对象后,我重新分配了删除时间戳的日期。我这样做是为了尽早解决问题,通过使用字符串操作并删除时间戳并仅将日期部分(作为字符串)分配给我的对象属性我确保如果有时间组件则将其设置为午夜。这一步可能是不必要的。

接收日期的数据对象属性是日期类型,而不是日期时间,sql表字段和更新数据库的存储过程的参数也是如此。

从客户端或开发计算机使用SQL Server Management Studio检查数据库,在数据库中显示日期为“2014-08-01”。

到目前为止一切顺利。

查询日期并显示问题:

我正在使用telerik报告,它托管一个objectdatasouce,它使用我编写的类返回我的对象​​列表。此代码在服务器端运行。数据类使用ASP.NET提供的SqlConnection,我假设它是ADO来打开和查询数据库。

使用此子句查询日期范围时,查询是非常向前的。

“s.AlarmDate&gt; = @ FromDate AND s.AlarmDate&lt; = @ ToDate”

如果我使用#8/1/2014#的FromDate,则查询找不到记录。经过实验,我发现我必须从FromDate中减去5个小时才能返回记录。

这意味着数据库的行为就好像数据库中的数据是'7/31/2014 19:00:00“。这是从'实际'日期开始的-5小时,恰好是UTZ偏移量CDT(中部夏令时)。

这也可能意味着我的FromDate提前5个小时。这对我来说意义不大,所以我不予理睬。

就是这样。没有涉及其他层,它就这么简单。