Zakładając, że LAST_TRANSACTION_DATE
to DATE
kolumna (lub TIMESTAMP
) obie wersje są bardzo złą praktyką.
W obu przypadkach DATE
kolumna zostanie niejawnie przekonwertowana na literał znakowy na podstawie bieżących ustawień NLS. Oznacza to, że z różnymi klientami uzyskasz różne wyniki.
Używając literałów daty zawsze użyj to_date()
z (!) maską formatu lub użyj literału daty ANSI. W ten sposób porównujesz daty z datami, a nie ciągi z ciągami. Więc dla równego porównania powinieneś użyć:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Pamiętaj, że użycie „MON” może nadal prowadzić do błędów z różnymi ustawieniami NLS ('DEC'
w porównaniu z 'DEZ'
lub 'MAR'
w porównaniu z 'MRZ'
). Jest znacznie mniej podatny na błędy przy użyciu numerów miesięcy (i czterocyfrowych lat):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
lub za pomocą literału daty ANSI
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Powodem, dla którego powyższe zapytanie najprawdopodobniej nic nie zwróci, jest to, że w Oracle DATE
kolumny zawierają również czas. Powyższe literały daty domyślnie zawierają godzinę 00:00
. Jeśli czas w tabeli jest inny (np. 19:54
), to oczywiście daty nie są równe.
Aby obejść ten problem, masz różne opcje:
- użyj
trunc()
w kolumnie tabeli, aby „znormalizować” czas do00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
to jednak uniemożliwi użycie indeksu zdefiniowanegoLAST_TRANSACTION_DATE
- użyj
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')
Problem wydajności pierwszego rozwiązania można obejść, tworząc indeks w dniu trunc(LAST_TRANSACTION_DATE)
które mogą być użyte przez to wyrażenie. Ale wyrażenie LAST_TRANSACTION_DATE = '30-JUL-07'
zapobiega również użyciu indeksu, ponieważ wewnętrznie jest on przetwarzany jako to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Ważne rzeczy do zapamiętania:
- Nigdy, przenigdy nie polegaj na niejawnej konwersji typu danych. będzie w pewnym momencie sprawią ci problemy. Zawsze porównuj prawidłowe typy danych
- Oracle
DATE
kolumny zawsze zawierają czas, który jest częścią reguł porównania.