Oracle
 sql >> база данни >  >> RDS >> Oracle

Equals(=) спрямо LIKE за тип данни за дата

Приемаме LAST_TRANSACTION_DATE е DATE колона (или TIMESTAMP ) тогава и двете версии са много лоша практика.

И в двата случая DATE колоната ще бъде имплицитно преобразувана в символен литерал въз основа на текущите настройки на NLS. Това означава, че с различни клиенти ще получите различни резултати.

Когато използвате литерали за дата винаги използвайте to_date() с(!) маска на формат или използвайте ANSI литерал за дата. По този начин сравнявате дати с дати, а не низове с низове. Така че за еднакво сравнение трябва да използвате:

LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')

Имайте предвид, че използването на „MON“ все още може да доведе до грешки с различни NLS настройки ('DEC' спрямо 'DEZ' или 'MAR' спрямо 'MRZ' ). Много по-малко е податливо на грешки при използване на номера на месеци (и четирицифрени години):

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 ) тогава, разбира се, датите не са равни.

За да заобиколите този проблем, имате различни опции:

  1. използвайте trunc() в колоната на таблицата, за да "нормализирате" времето до 00:00 trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 това обаче ще предотврати използването на индекс, дефиниран на LAST_TRANSACTION_DATE
  2. използвайте 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'

Важните неща, които трябва да запомните:

  1. Никога, никога не разчитайте на имплицитно преобразуване на тип данни. Това ще ви създава проблеми в даден момент. Винаги сравнявайте правилните типове данни
  2. Oracle DATE колоните винаги съдържат време, което е част от правилата за сравнение.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL:Използвайте последователност при вмъкване с Select Statement

  2. Как да предадете списък с обекти на Java към съхранената процедура на Oracle с помощта на MyBatis?

  3. Активиране на TLS в Oracle Apps R12.2

  4. Заявка на Oracle за извличане на имена на колони

  5. Как да премахнете дубликатите от списъка, разделен от пространството от Oracle regexp_replace?