あなたが提供した情報を考えると、最も可能性の高い説明は、depositDate
列がDATETIMEまたはTIMESTAMPとして定義されているということです。これらのデータ型は、日付に加えて時間値(1秒までの解像度)を格納することに注意してください。例えば
'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列の述語の場合、「日」を取得する通常のパターンは、特定の日の深夜から翌日の深夜までの範囲スキャンを実行することです。確認したいのは、列が翌日の深夜よりも少ないかどうかです。
'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'
あなたの場合、あなたはすでに「終了日」の値を持っているので、最も簡単な変更は単にクエリテキストを変更することです。
渡す日付値に1日を追加し、比較演算子をから<=
に変更するだけ<
です。(ここでは、日付部分のみを指定し、時間部分をデフォルトで深夜に設定できると想定しています。)
... d.depositDate < DATE_ADD('${endDateString}',INTERVAL 1 DAY)"
DATE
このパターンは、、DATETIME
およびで同様に機能するため、このパターンをお勧めしTIMESTAMP
ます。
(注:このパターンを好むもう1つの理由は、より細かい解像度の「特定の時点」の値で機能するためです(たとえば、Microsoft SQL Server DATETIMEは、精度が3ミリ秒で、<= 23:59.59のチェックを実行します)。結局不十分です。)
コードは、引数の値が日付のみであること、または時刻コンポーネントが深夜の日付であることを確認できますが、引数をaaでラップすることにより、SQLクエリにこれを実行させるのは簡単です。CAST( AS DATE)
注:関数内で列参照をラップすることは避けたいと思います。d.depositDate
これは、MySQLがインデックス範囲スキャン操作を実行する機能を無効にするためです(述語を満たすため)。
注:SQLインジェクションの脆弱性に関する通常の警告はすべてここに適用されます。引数の値がユーザーによって指定されている場合は、バインドパラメーターを使用するか、指定された....値をエスケープする必要があります。
悪意のあるユーザーが次のような値を提供するとどうなるかを考えてみてください。
2012-07-20'; DELETE FROM Deposit ; SELECT '1
どのステートメントがデータベースに渡されるかを検討してください。このような攻撃を阻止するために、これに対処するためのいくつかのアプローチがあります。