Angenommen LAST_TRANSACTION_DATE
ist ein DATE
Spalte (oder TIMESTAMP
) dann sind beide Versionen sehr schlechte Praxis.
In beiden Fällen das DATE
Spalte wird basierend auf den aktuellen NLS-Einstellungen implizit in ein Zeichenliteral konvertiert. Das bedeutet, dass Sie bei verschiedenen Clients unterschiedliche Ergebnisse erhalten.
Bei Verwendung von Datumsliteralen immer Verwenden Sie to_date()
mit(!) einer Formatmaske oder verwenden Sie ein ANSI-Datumsliteral. Auf diese Weise vergleichen Sie Daten mit Daten und nicht Zeichenfolgen mit Zeichenfolgen. Für den gleichen Vergleich sollten Sie also verwenden:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Beachten Sie, dass die Verwendung von 'MON' bei unterschiedlichen NLS-Einstellungen immer noch zu Fehlern führen kann ('DEC'
vs. 'DEZ'
oder 'MAR'
vs. 'MRZ'
). Die Verwendung von Monatszahlen (und vierstelligen Jahreszahlen) ist viel weniger fehleranfällig:
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
oder mit einem ANSI-Datumsliteral
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Der Grund, warum die obige Abfrage sehr wahrscheinlich nichts zurückgibt, ist der in Oracle DATE
Spalten enthalten auch die Uhrzeit. Die obigen Datumsliterale enthalten implizit die Uhrzeit 00:00
. Wenn die Uhrzeit in der Tabelle abweicht (z. B. 19:54
) dann sind die Daten natürlich nicht gleich.
Um dieses Problem zu umgehen, haben Sie verschiedene Möglichkeiten:
- benutze
trunc()
in der Tabellenspalte, um die Uhrzeit auf00:00
zu "normalisieren".trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
dies verhindert jedoch die Verwendung eines amLAST_TRANSACTION_DATE
definierten Index - benutze
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')
Das Leistungsproblem der ersten Lösung könnte umgangen werden, indem ein Index auf trunc(LAST_TRANSACTION_DATE)
erstellt wird die von diesem Ausdruck verwendet werden könnten. Aber der Ausdruck LAST_TRANSACTION_DATE = '30-JUL-07'
verhindert auch eine Indexverwendung, da es intern als to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
verarbeitet wird
Die wichtigsten Dinge, die Sie sich merken sollten:
- Verlassen Sie sich niemals auf die implizite Datentypkonvertierung. Es wird irgendwann Probleme machen. Vergleichen Sie immer die richtigen Datentypen
- Oracle
DATE
Spalten enthalten immer eine Zeit, die Teil der Vergleichsregeln ist.