sql >> Base de Datos >  >> RDS >> Oracle

Es igual a (=) frente a LIKE para el tipo de datos de fecha

Asumiendo LAST_TRANSACTION_DATE es una DATE columna (o TIMESTAMP ) entonces ambas versiones son muy malas prácticas.

En ambos casos el DATE la columna se convertirá implícitamente en un carácter literal basado en la configuración actual de NLS. Eso significa que con diferentes clientes obtendrás resultados diferentes.

Cuando se usan literales de fecha siempre use to_date() con (!) una máscara de formato o use un literal de fecha ANSI. De esa manera, compara fechas con fechas, no cadenas con cadenas. Entonces, para la comparación igual, debe usar:

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

Tenga en cuenta que el uso de 'MON' aún puede generar errores con diferentes configuraciones de NLS ('DEC' contra 'DEZ' o 'MAR' contra 'MRZ' ). Es mucho menos propenso a errores usando números de meses (y años de cuatro dígitos):

LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')

o usando un literal de fecha ANSI

LAST_TRANSACTION_DATE = DATE '2007-07-30'

Ahora, la razón por la que es muy probable que la consulta anterior no devuelva nada es que en Oracle DATE las columnas también incluyen la hora. Los literales de fecha anteriores contienen implícitamente la hora 00:00 . Si la hora en la tabla es diferente (por ejemplo, 19:54 ) entonces, por supuesto, las fechas no son iguales.

Para solucionar este problema tienes diferentes opciones:

  1. usa trunc() en la columna de la tabla para "normalizar" el tiempo a 00:00 trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 sin embargo, esto evitará el uso de un índice definido en LAST_TRANSACTION_DATE
  2. usar 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')

El problema de rendimiento de la primera solución podría solucionarse creando un índice en trunc(LAST_TRANSACTION_DATE) que podría ser utilizado por esa expresión. Pero la expresión LAST_TRANSACTION_DATE = '30-JUL-07' también evita el uso de un índice porque internamente se procesa como to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'

Las cosas importantes para recordar:

  1. Nunca, jamás confíe en la conversión implícita de tipos de datos. lo hará darte problemas en algún momento. Compare siempre los tipos de datos correctos
  2. Oráculo DATE las columnas siempre contienen un tiempo que es parte de las reglas de comparación.