En supposant LAST_TRANSACTION_DATE
est une DATE
colonne (ou TIMESTAMP
) alors les deux versions sont de très mauvaises pratiques.
Dans les deux cas, la DATE
colonne sera implicitement convertie en un littéral de caractère basé sur les paramètres NLS actuels. Cela signifie qu'avec différents clients, vous obtiendrez des résultats différents.
Lors de l'utilisation de littéraux de date toujours utilisez to_date()
avec (!) un masque de format ou utilisez un littéral de date ANSI. De cette façon, vous comparez des dates avec des dates et non des chaînes avec des chaînes. Donc, pour la comparaison égale, vous devez utiliser :
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Notez que l'utilisation de 'MON' peut toujours entraîner des erreurs avec différents paramètres NLS ('DEC'
vs 'DEZ'
ou 'MAR'
vs 'MRZ'
). Il est beaucoup moins sujet aux erreurs en utilisant des nombres de mois (et des années à quatre chiffres) :
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
ou en utilisant un littéral de date ANSI
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Maintenant, la raison pour laquelle la requête ci-dessus est très susceptible de ne rien renvoyer est que dans Oracle DATE
les colonnes incluent également l'heure. Les littéraux de date ci-dessus contiennent implicitement l'heure 00:00
. Si l'heure indiquée dans le tableau est différente (par exemple, 19:54
) alors bien sûr les dates ne sont pas égales.
Pour contourner ce problème, vous disposez de différentes options :
- utiliser
trunc()
sur la colonne du tableau pour "normaliser" l'heure à00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
cela empêchera cependant l'utilisation d'un index défini leLAST_TRANSACTION_DATE
- utiliser
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')
Le problème de performances de la première solution pourrait être contourné en créant un index sur trunc(LAST_TRANSACTION_DATE)
qui pourrait être utilisé par cette expression. Mais l'expression LAST_TRANSACTION_DATE = '30-JUL-07'
empêche également l'utilisation d'un index car il est traité en interne comme to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Les choses importantes à retenir :
- Ne vous fiez jamais, au grand jamais, à la conversion implicite des types de données. Cela va vous donner des problèmes à un moment donné. Comparez toujours les bons types de données
- Oracle
DATE
les colonnes contiennent toujours une heure qui fait partie des règles de comparaison.