2012-04-30 87 views
4

我运行SQL Server 2005在查询日期范围内查找记录。该WHERE条款如下:SQL Server的日期比较忽略一年

WHERE (CONVERT(NVARCHAR, fldPublishedDate, 101) >= '" & toDate & 
    "' AND CONVERT(NVARCHAR, fldPublishedDate, 101) <= '" & fromDate & "')" 

toDatefromDate正在进入这样04/01/200504/30/2005

我得到的结果是肯定的所有4月1日至30日之间,但不同年份,从2005年(时数据收集开始)到2012年。它看起来像当年只是从比较忽略。我在这里错过了什么吗?

感谢您抽出时间来阅读。

+1

使用参数来防止SQL注入,并通过日期,而不是字符串。 –

+0

谢谢大家回答。我知道注入风险,但这更多的是内部工具,所以我并不太担心。此外,这是由其他人开发的,我只是想解决它。我现在甚至没有访问SQL Server的权限,只有代码。 –

+0

此外,我不知道我有什么问题,我没有注意到转换为nvarchar,显然,这是问题。我更感兴趣的是找出它为什么在月份和日期上工作,而不是在一年中工作。奇怪的。 –

回答

6

你为什么要转换为字符串?当然这并不如预期的那样。你的意思是:

IF '12/02/2010' > '09/12/2012' 

当然这是正确的。您应该说:

WHERE fldPublishedDate >= '20050401' 
    AND fldPublishedDate < DATEADD(DAY, 1, '20050430'); 

只有在仅比较日期范围时,您不需要将列转换为日期。最重要的是,您应该以明确的格式传递日期,以避免区域和语言设置(例如YYYYMMDD)。 101是不是一种安全的风格,因为英格兰人在哪一个月是04/06/2012?那是六月,而不是四月。我怀疑你应该在你的(传统的ASP?)代码中更好地格式化这些日期,或者从你使用的任何语言中传递适当的日期时间数据类型。最后,不要使用不带长度的NVARCHAR:http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx

+1

+1不能说更好 - 比较日期**作为日期**而不是字符串:-) –

2

如果fldPublishedDate是SQL Server中的日期,那么为什么要将它转换为nvarchar来做比较。您可以将您toDatefromDate转换为datetime,做的比较

declare @toDate nvarchar(50) 
declare @fromDate nvarchar(50) 

set @toDate = '04/01/2005' 
set @fromDate = '04/30/2005' 

select cast(@toDate as datetime), cast(@fromDate as datetime) 

results: 
ToDate      FromDate 
2005-04-01 00:00:00.000  2005-04-30 00:00:00.000 

然后在您的WHERE条款:

WHERE fldPublishedDate >= cast(@toDate as datetime) 
AND fldPublishedDate <= cast(@fromDate as datetime) 
2

假设fldPublishedDate是一个datetime,并要对唯一date比较。

在SQL 2008,用方便,花花公子日期类型:

WHERE CONVERT(date, fldPublishedDate) >= CONVERT(date, '" & toDate & 
"' AND CONVERT(date, fldPublishedDate) <= CONVERT(date, '" & fromDate & "'" 

在< SQL 2008,您可以用疯狂的语法:

WHERE DATEADD(dd, DATEDIFF(dd, 0, fldPublishedDate), 0) >= CONVERT(datetime, '" & toDate & 
"' AND DATEADD(dd, DATEDIFF(dd, 0, fldPublishedDate), 0) <= CONVERT(datetime, '" & fromDate & "'" 

Tehcnically,SQL会将您datetime字符串为你 - 所以你可以离开你的价值观的转换。

此外,你应该电文读出SQL注入和参数 - 这是更容易编写,更易于阅读,更安全的为好。赢,赢,赢。

+0

OP说他使用SQL Server ** 2005 ** ...所以我们不能使用'DATE'。但是你肯定在SQL注入方面有一个非常有效的点 –

+0

你能解释为什么你需要在where子句的两个分支中进行转换吗?如果右侧是午夜的日期,如果左侧是午夜的同一日期,或者凌晨4点或晚上11点,那么它们会有什么不同? –