Assuming LAST_TRANSACTION_DATE
is a DATE
column (or TIMESTAMP
) then both version are very bad practice.
In both cases the DATE
column will implicitly be converted to a character literal based on the current NLS settings. That means with different clients you will get different results.
When using date literals always use to_date()
with(!) a format mask or use an ANSI date literal. That way you compare dates with dates not strings with strings. So for the equal comparison you should use:
LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')
Note that using 'MON' can still lead to errors with different NLS settings ('DEC'
vs. 'DEZ'
or 'MAR'
vs. 'MRZ'
). It is much less error prone using month numbers (and four digit years):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
or using an ANSI date literal
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Now the reason why the above query is very likely to return nothing is that in Oracle DATE
columns include the time as well. The above date literals implicitly contain the time 00:00
. If the time in the table is different (e.g. 19:54
) then of course the dates are not equal.
To workaround this problem you have different options:
- use
trunc()
on the table column to "normalize" the time to 00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
this will however prevent the usage of an index defined on LAST_TRANSACTION_DATE
- use
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')
The performance problem of the first solution could be worked around by creating an index on trunc(LAST_TRANSACTION_DATE)
which could be used by that expression. But the expression LAST_TRANSACTION_DATE = '30-JUL-07'
prevents an index usage as well because internally it's processed as to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
The important things to remember:
- Never, ever rely on implicit data type conversion. It will give you problems at some point. Always compare the correct data types
- Oracle
DATE
columns always contain a time which is part of the comparison rules.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…