2012-07-23 32 views
3

我有一個C#程序將作爲Windows計劃任務運行。該程序將加載,運行SQL查詢,通過電子郵件發送存儲在數據集中的結果,然後關閉。除了使用Yesterdays日期之外,我擁有一切。如何將昨天的日期分配給參數C#

這裏是我當前的查詢:

SELECT  Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM   Paid_Out_Tb 
WHERE  (Store_Id = 1929) AND (Paid_Out_Datetime BETWEEN @startdate AND @enddate) 

很顯然,我需要在查詢的時間分配@startdate和@EndDate。因爲我需要12AM到1159PM這是開始和結束的原因。舉個例子。如果我想今天運行程序,它會搜索昨天(23日),所以@startdate將被分配7/22/12 00:00:00和@ enddate將被分配7/22/12 23:59:59 .. 。

在查詢而不是程序中做它更合理嗎?如果是這樣,我將如何更改查詢?

+0

不要之間使用的。請閱讀http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx和http://sqlblog.com/。 blog/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx – 2012-07-23 17:15:08

回答

2

與日期間隔打交道時,不要使用between。使用>=<更容易和更安全。

像這樣的東西會給你昨天沒有參數的東西。

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM Paid_Out_Tb 
WHERE Store_Id = 1929 AND 
     Paid_Out_Datetime >= dateadd(day, datediff(day, 0, getdate())-1, 0) and 
     Paid_Out_Datetime < dateadd(day, datediff(day, 0, getdate()), 0) 
+0

我用這個......在收集數據方面更清潔。謝謝! – Shmewnix 2012-07-23 17:32:49

0

我假定你都在尋找的東西這樣

DateTime yesterdDaysDateTime = DateTime.Now.AddDays(-1); 
4

你可以計算出在C#昨天開始:

var yesterday = DateTime.Now.AddDays(-1); 
var startOfYesterday = new DateTime(yesterday.Year, yesterday.Day, yesterday.Month); 
com.Parameters.AddWithValue("@enddate", startOfYesterday); 

如果您使用的SQL Server 2008+,你可以改變數據類型從datetimedate。後者只能存儲日期,因此您不必擔心日期時間部分。

+2

使用'Today'而不是'Now',你不需要執行「start的昨天「計算。 – 2012-07-23 16:54:15

+0

這是SQL 2000,我會嘗試在C#中的建議。 – Shmewnix 2012-07-23 16:54:18

0

您應該始終使用參數化查詢。

爲了支持您正在尋找的內容,您可以在昨天的日期中放入一個變量並將該變量傳遞給您的參數。

5

對現有答案略有改進,始終獲得昨天的開始,無需致電DateTime構造函數。

var todayStart = DateTime.Today; 
var yesterdayStart = todayStart.AddDays(-1); 
var yesterdayEnd = todayStart.AddSeconds(-1); // Ick... 

注意,這將使用當前系統時區的「今天」的含義 - 你確定這就是你想要什麼?您不妨考慮使用:

var todayUtcStart = DateTime.UtcNow.Date; 
... 

這是一個恥辱,BETWEEN治療終點的包容性 - 如果它是相當於

start <= value && value < end 

,那麼你可以只舉兩個午夜值,這將是更清晰。

同時還要注意它會不會與數據庫中的任何清潔劑進行交互,用於日期和時間的其他用途,你不妨具體考慮我Noda Time庫,其中包含一個數據類型爲代表日期(另一個用於「一天中的時間」)等。目標無疑是澄清使用日期和時間的代碼。如果沒有,我失敗了!

+0

Skeet不需要成爲西部最快的槍... – canon 2012-07-23 16:55:52

+1

SQL Server默認存儲幾分之一秒,所以-1秒不會修復它。更好地通過第二天的開始,並使用'<'代替'<=' – Andomar 2012-07-23 16:58:33

+0

@Andomar:我只是想問問題。這就是爲什麼我說這是BETWEEN有效'<='的痛苦。格兒。 – 2012-07-23 19:21:40

0

這也可以工作,但是有一個缺點表現:

DateTime yesterday = DateTime.Today; 
Thread.Sleep(1000 * 60 * 60 * 24); 
0

你也可以這樣做在SQL:

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, 
     Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM   Paid_Out_Tb 
WHERE  (Store_Id = 1929) 
AND (Paid_Out_Datetime BETWEEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
    AND dateadd(second, -1, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE())))) 
0

如果你希望把查詢本身:

select (date_trunc('day', NOW()) - INTERVAL '1 day'); -- Yesterday Start 
select (date_trunc('day', NOW()) - INTERVAL '1 second'); -- Yesterday End 
+0

這是Oracle的語法吧?我相信這個問題是針對SQL Server – Andomar 2012-07-23 17:09:12

+0

不,是postgres。 – FabianoLothor 2012-07-23 17:36:20