2011-12-13 13 views
0

在SQL Server 2008R2中,在兩個日期之間獲取數據不起作用。在日期範圍之間獲取行在SQL Server中不起作用

我使用以下代碼來從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) 

它不能正常工作,推動我堅果..

我做錯了嗎?..

+2

我不明白爲什麼要轉換的日期爲varchar爲查詢。你不能只保留它作爲日期嗎? – Kangkan

+0

Iam這樣做是因爲在數據庫INV.CREATED_DATE字段中有數據類型datetime,所以以此格式'2011-12-13 11:12:37.000'返回數據並從我的應用程序文本框中接收日期並以此格式發送參數值' 2011-12-13' 。這是如何以更好的方式完成的......即在指定日期之間獲取日期。 – SST

+0

如果您的查詢參數在varchar中,請將它們轉換爲datetime。 – Kangkan

回答

2

既然你是在SQL Server 2008 R2中,你可以只是一切都轉換爲DATE格式:由於您使用的DATE

SELECT * 
FROM dbo.INVOICES INV 
WHERE CAST(INV.CREATED_DATE AS DATE) 
     BETWEEN CAST(@startdate AS DATE) AND CAST(@enddate AS DATE) 

,你是獨立於任何日期格式的或語言設置或任何這些棘手的功能。 SQL Server只會比較日期 - 因爲它應該。

,當然還有:如果你讓你的存儲過程的參數@startdate@enddate從一開始就成爲DATE型的,那麼你可以節省自己的這兩個CAST操作呢!

SELECT * 
FROM dbo.INVOICES INV 
WHERE CAST(INV.CREATED_DATE AS DATE) BETWEEN @startdate AND @enddate 

(如果你做DATE類型的CREATED_DATE - 你甚至可以忘記在聲明最後CAST,太!)

+0

假設'CREATED_DATE'是'datetime'類型,並且有一個索引,那麼SQL Server 2008會在' CREATED_DATE'是否投射到'日期'? –

+0

@MichałPowaga:我不確定 - 我們必須嘗試一下,看看... –

+0

我會,但我沒有SQL Server 2008,所以我不能,這就是爲什麼我問。 –

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

Default setting is yyyy-MM-dd

如果使用105這意味着你正在試圖解析日期格式dmy,所以執行下面添加一行在查詢前上方。

SET DATEFORMAT DMY