Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Równe (=) vs. LIKE dla typu danych daty

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:

  1. użyj trunc() w kolumnie tabeli, aby „znormalizować” czas do 00:00 trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 to jednak uniemożliwi użycie indeksu zdefiniowanego LAST_TRANSACTION_DATE
  2. 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:

  1. Nigdy, przenigdy nie polegaj na niejawnej konwersji typu danych. będzie w pewnym momencie sprawią ci problemy. Zawsze porównuj prawidłowe typy danych
  2. Oracle DATE kolumny zawsze zawierają czas, który jest częścią reguł porównania.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wykrywanie cykli z rekurencyjnym faktoringiem podzapytań

  2. Jak dowiedzieć się, kiedy tabela Oracle była ostatnio aktualizowana?

  3. Jak korzystać z funkcji Oracle LITAGG

  4. Zmiana hasła w Oracle SQL Developer

  5. Dlaczego klauzula Oracle IN ma limit 1000 tylko dla danych statycznych?