2014-12-19 128 views
0

我在我的表中有一个日期时间字段,我需要在where子句中使用。 的字段名是DatumAanname 在我dataviewgrid它显示例如“16/12/2014 15时57分04秒”SQL Server比较日期时间字段

我看着网页从微软与所有的转换日期时间的选择,但这种格式不似乎在该页面上。 我可以看到有最接近的格式为“16 12 2014 15点57分04秒”,这应该是113

我试过这样

SELECT o.DatumAanname, 
    (convert(DATETIME, '16 dec 2014 15:57:04:000', 113)), 
    (convert(DATETIME, '16 dec 2014 15:57:04', 113)), 
    (convert(DATETIME, o.DatumAanname, 113)) 
FROM vwOpdracht o 

这将返回4个字段的查询,所有看起来完全一样

但是当我做

where (convert(datetime, o.DatumAanname, 113)) = (convert(datetime, '16 dec 2014 15:57:04:000', 113)) 

返回0记录

我在这里做错了什么?

+0

是否'O操作。DatumAanname'具有'16 dec 2014 15:57:04'的日期 – 2014-12-19 08:43:54

+0

113是'dd mon yyyy hh:mm:ss:mmm' - 'mmm'部分必然是 – 2014-12-19 08:46:49

+0

正如我在我的问题中所说的,datagridview显示记录价值“16/12/2014 15:57:04”所以是的,价值在那里。另外在我的问题,我说我的查询显示4列完全相同的价值,所以如何可能这个值不在那里N – GuidoG 2014-12-19 08:49:10

回答

1

日期没有格式,它们是具有自己的二进制存储的本地类型。格式和转换仅适用于从/转换为字符串时,如果使用不兼容的排序规则和文化,它们经常会导致问题。

避免问题的最佳方法是简单地完全删除字符串:在表中使用日期类型列并使用参数化查询进行查询。实际上,如果日期存储为表格中的文本,则存在没有通用和防故障的方式来解决问题。

传递强类型值而不是字符串(例如C#中的DateTime,T-SQL中的datetime,datetime2)。例如:

where o.DatumAanname= @dateParam 

如果值匹配,将返回匹配项。

如果传递日期参数是不可能的,你应该只使用the unambiguous ISO8691 format,如:

where o.DatumAanname = '2014-12-16T15:57:04' 

如果你想通过日期值只可以使用未分离的格式上也毫不含糊

where o.DatumAanname = '20141216' 

有一点要注意的是,日期值必须完全匹配,直到毫秒。通常日期用于范围查询中,这不是问题。但在平等查询中,这可能是一个问题。

您可以通过使用datetime2(0)作为字段类型来避免这种情况,从而确保根本不存储毫秒。

另一种选择是使用范围,而不是一个平等的查询,如:

where o.DatumAanname between '2014-12-16T15:57:04' and '2014-12-16T15:57:04.999' 

where o.DatumAanname between '2014-12-16T15:57:00' and '2014-12-16T15:57:59' 

如果你想分钟级精度

+0

不幸的是,数据库是使用datetime而不是datetime2创建的。我试图将该字段投射到datetime2,但仍包含毫秒。 – GuidoG 2014-12-19 09:29:11

+0

datetime2类型接受一个精度参数,就像'numeric'一样,指定毫秒精度。 'datetime2(0)'不包含毫秒。您应该小心,因为转换或在字段上应用任何类型的函数都会阻止优化器使用索引。优化器对日期有特殊的处理,但是您应该检查执行计划以确保您不会最终进行全表扫描。也许你应该修改你的查询到你想要的秒和下一个(或者你想要的任何精度级别)之间的范围查询, – 2014-12-19 09:36:20