2014-02-15 33 views
0

我想要做的是比較DateTime變量和SQL Server中的表內的日期如果這兩個日期之間的差異小於30分鐘select選擇查詢將返回一些值我使用C#發DateTime變量在sql server中比較兩個日期分鐘

string query = "Select * from LoginAttempts where IP_ADDRESS='" + Ipadress + "' and ATTEMPTS<"+MaxLoginAttempts+" and (GETDATE()-LOGIN_DATE)<30"; 

and (GETDATE()-LOGIN_DATE)<30我知道這是一個錯誤的說法,但我應該怎麼解決?

回答

5

首先,停止動態建立你的SQL這樣的。改用參數化的SQL。我想你只想要DATEADD。如果您知道LOGIN_DATE將始終處於過去狀態,則只需要爲此添加30分鐘,並檢查結果是否晚於GETDATE() - 或等同地從現在開始減去30分鐘,並檢查LOGIN_DATE是否晚於結果:

string query = @"Select * from LoginAttempts where [email protected]' 
       and ATTEMPTS < @MaxLoginAttempts 
       and LOGIN_DATE > DATEADD(minute, -30, GETDATE())"; 
// Then fill in the parameters in the SqlCommand 

正如在評論中指出,應用DATEADDGETDATE()而不是向LOGIN_DATE允許更多的優化,因爲它只需要將每一行,而不是一次進行一次,並允許任何LOGIN_DATE指數是有效的。

您可以代替這種情況下使用DATEDIFF,但它是值得的注意,DATEDIFF並不總是做什麼你可能指望它,因爲它是關於「過境通道」。這裏沒有什麼問題,但這意味着9月1日和8月31日之間的差異是1個月,9月30日和8月1日之間的差異也是如此。

在這種情況下,影響只會是(比如說)10:00:59和10:30:00會被視爲30分鐘,儘管他們只有只需超過29分鐘;而儘管相隔將近30分鐘,但10:00:00至10:29:59之間的差距也將爲29分鐘。所以你的實際使用時間會有些不一致。

+0

儘管我同意這些言論,但我對看到'和DATEADD(分鐘,30,LOGIN_DATE)> GETDATE();'。應該總是將該函數應用於常量並保留字段,以便查詢處理器可以使用統計信息,甚至更好地使用索引(如果存在)在這種情況下,您必須將構造反轉爲'和LOGIN_DATE> DATEADD(分鐘,-30,GETDATE());' – deroby

+0

@deroby:是的,這是有道理的,並且是一個非常好的點 - 我會編輯。 –

2

試試這個:

DATEDIFF(MINUTE, GETDATE(), LOGIN_DATE) 

所以整個查詢應該是這樣的:

string query = "Select * from LoginAttempts where IP_ADDRESS='" + Ipadress + "' 
and ATTEMPTS<"+MaxLoginAttempts+" and DATEDIFF(MINUTE, GETDATE(), LOGIN_DATE)<30"; 
+0

請注意,這可以給一些奇怪的結果 - 請參閱我的答案的最後一段爲例。 –

+0

與Jon Skeet相同的評論。像DATEDIFF(MINUTE,GETDATE(),LOGIN_DATE)<30'這樣的結構將強制掃描數據,而不是能夠有效地使用索引=( – deroby