数据库是没有时间组件的日期类型。在查询中,我放置了一个时间组件来确保正确的开始和结束时间。如果我将开始日期调整为UTZ时间,则查询有效。如果我在午夜之前将开始日期调整为昨天1秒,则不起作用。这向我表明数据库将日期存储为UTZ但似乎不可能。
我有这个:
表
表中有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个小时。这对我来说意义不大,所以我不予理睬。
就是这样。没有涉及其他层,它就这么简单。
答案 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个小时。这对我来说意义不大,所以我不予理睬。
就是这样。没有涉及其他层,它就这么简单。