在SQL Server 2008R2中,在两个日期之间提取数据不起作用。
我使用以下代码从INVOICE
表中获取CREATED_DATE
介于@startdate
和@enddate
之间的行,这些是我发送给的Select *
from INVOICES INV
where CONVERT(Varchar(10), INV.CREATED_DATE, 105)
BETWEEN CONVERT(VARCHAR(10), @startdate, 105)
AND CONVERT(VARCHAR(10), @enddate, 105)
存储过程。
{{1}}
它工作不正常,让我疯了..
我做错了什么?..
答案 0 :(得分:8)
select * from
invoices inv
where inv.created_date >= dateadd(dd, 0, datediff(dd, 0, @startdate))
and inv.created_date < dateadd(dd, 1, datediff(dd, 0, @enddate))
首先,不要convert你的开始/结束和列的日期为varchar,如果你这样做,请记住105
(返回dd-mm-yyyy)不是可比的,112
(返回yyyymmdd)会更好(当你只对日期部分感兴趣时)。但我所说的最好不要转换,只是比较日期。
<强>加:
几乎没有解释:dateadd(dd, 0, datediff(dd, 0, @startdate))
- 仅返回日期时间的日期部分,dateadd(dd, 1, datediff(dd, 0, @startdate))
- 仅返回第二天的日期部分。
查询返回包含参数的所有行(无论小时数)。
答案 1 :(得分:2)
由于您使用的是SQL Server 2008 R2,因此您只需将所有内容转换为DATE
格式:
SELECT *
FROM dbo.INVOICES INV
WHERE CAST(INV.CREATED_DATE AS DATE)
BETWEEN CAST(@startdate AS DATE) AND CAST(@enddate AS DATE)
由于您使用的是DATE
类型,因此您可以独立于任何日期格式或语言设置或任何棘手的功能。 SQL Server只会比较日期。
当然:如果您从一开始就将存储过程参数@startdate
和@enddate
设为DATE
类型,那么您可以自己保存这两个CAST
操作也是!
SELECT *
FROM dbo.INVOICES INV
WHERE CAST(INV.CREATED_DATE AS DATE) BETWEEN @startdate AND @enddate
(如果你的CREATED_DATE
类型DATE
- 你甚至可以忘记声明中的最后CAST
!)
答案 2 :(得分:1)
Default setting is yyyy-MM-dd
如果您使用105
,这意味着您尝试将日期解析为格式dmy
,那么在执行查询顶部的下方行添加之前。
SET DATEFORMAT DMY