LAST_TRANSACTION_DATE
を想定 DATE
です 列(またはTIMESTAMP
)その後、両方のバージョンは非常に悪い習慣です。
どちらの場合も、DATE
列は、現在のNLS設定に基づいて暗黙的に文字リテラルに変換されます。つまり、クライアントが異なれば、結果も異なります。
日付リテラルを使用する場合常に to_date()
を使用する with(!)フォーマットマスクまたはANSI日付リテラルを使用します。このようにして、日付を文字列と文字列ではなく日付と比較します。したがって、同等の比較を行うには、次を使用する必要があります:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
'MON'を使用すると、異なるNLS設定('DEC'
)でエラーが発生する可能性があることに注意してください。 vs. 'DEZ'
または'MAR'
vs. 'MRZ'
)。月番号(および4桁の年)を使用すると、エラーが発生しにくくなります。
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
またはANSI日付リテラルを使用する
LAST_TRANSACTION_DATE = DATE '2007-07-30'
上記のクエリが何も返さない可能性が非常に高い理由は、OracleのDATE
にあるためです。 列には時間も含まれます。上記の日付リテラルには、暗黙的に時刻00:00
が含まれています 。テーブル内の時間が異なる場合(例:19:54
)そしてもちろん、日付は等しくありません。
この問題を回避するには、さまざまなオプションがあります。
-
trunc()
を使用する テーブルの列で、時間を00:00
に「正規化」しますtrunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
ただし、これにより、LAST_TRANSACTION_DATE
で定義されたインデックスを使用できなくなります。 -
between
を使用する
LAST_TRANSACTION_DATE between to_date('2007-07-30 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and to_date('2007-07-30 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
最初のソリューションのパフォーマンスの問題は、trunc(LAST_TRANSACTION_DATE)
にインデックスを作成することで回避できます。 その式で使用できます。ただし、式LAST_TRANSACTION_DATE = '30-JUL-07'
内部的にはto_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
として処理されるため、インデックスの使用も防止します。
覚えておくべき重要なこと:
- 暗黙のデータ型変換に依存しないでください。 ある時点で問題が発生します。常に正しいデータ型を比較してください
- Oracle
DATE
列には常に、比較ルールの一部である時間が含まれています。