考慮您所提供的信息,最可能的解釋depositDate
列被定義爲DATETIME或TIMESTAMP。請注意,除日期外,這些數據類型還會存儲時間值(分辨率降至一秒)。例如
'2012-07-20 11:35:46'
比較一個DATETIME值所以一個DATE文字(沒有時間組件),例如,
'2012-07-20 11:35:46' <= '2012-07-20'
等同於用文字與午夜的時間值的DATETIME一個比較:
'2012-07-20 11:35:46' <= '2012-07-20 00:00:00'
這顯然會返回FALSE。這就是爲什麼你的查詢沒有返回你期望的行的最可能的解釋。
修復建議:
有關DATETIME和TIMESTAMP列謂詞,正常模式得到一個「天」是從一天的午夜做範圍掃描高達午夜次日。我們要檢查什麼是列是否大於次日午夜LESS:
'2012-07-20 11:35:46' < DATE_ADD('2012-07-20', INTERVAL 1 DAY)
這相當於相較於21日午夜。
'2012-07-20 11:35:46' < '2012-07-21 00:00:00'
在你的情況,因爲你已經有一個「結束日期」的值,最簡單的變化是簡單地更改查詢文本。
只需在您傳入的日期值中添加一天,然後將比較運算符從<=
更改爲<
。 (我這裏假設你是隻供應日期部分,並允許部分時間默認爲午夜。)
... d.depositDate < DATE_ADD('${endDateString}',INTERVAL 1 DAY)"
我們更喜歡這種模式,因爲它同樣適用於DATE
,DATETIME
和TIMESTAMP
。(注意:我們更喜歡這種模式的另一個原因是因爲它可以以更高分辨率的「時間點」值工作(例如,Microsoft SQL Server DATETIME,其精度可低至3毫秒,並且可以執行< = 23:59.59不足。)
您的代碼可以確保參數值僅爲日期,或者是具有午夜時間組件的日期,但通過SQL查詢執行此操作很容易將你的論點打包在aa中CAST( AS DATE)
注意:你想避免在任何函數中包裝列引用d.depositDate
,因爲這會禁用MySQL的abil可以執行索引範圍掃描操作(以滿足謂詞)。
注:所有關於SQL注入漏洞通常的警告適用於這裏,如果參數值是由用戶提供的,你想要麼使用綁定的參數或逃避提供....值
考慮當惡意用戶提供如下值時會發生什麼:
2012-07-20'; DELETE FROM Deposit ; SELECT '1
考慮將哪些語句傳遞到數據庫。處理這個問題有幾種方法來阻止這種攻擊。
哇,這真棒,@ spencer7593!我忘記了時間部分,默認爲零。 (我曾嘗試挖掘這個答案,但沒有打神奇的搜索詞組合。)我也非常感謝包裝列引用的注意事項;我沒有意識到這一點,這是一個很好的提示。還要感謝關於漏洞的說明;幸運的是,輸入被控制。 – Alexx 2012-07-23 15:17:10