Reputation: 826
I am finding it strenuous to work with dates in my customized environment. I have a request to add a where clause which caters to specific dates but I just cannot get oracle to budge. Any ideas anyone please.
select created_date, cast(created_date as date) as created_date_cast
from mytable;
created_date created_date_cast
04-Mar-20 05.21.15.772000 AM 3/4/2020 5:21:15 AM
04-Mar-20 05.21.15.709000 AM 3/4/2020 5:21:15 AM
04-Mar-20 05.17.14.902000 AM 3/4/2020 5:14:14 AM
28-Feb-20 01.15.25.702700 AM 2/28/2020 1:15:25 AM
When I try to add a where
clause the snippet blows up with the error:
select created_date, cast(created_date as date) as created_date_cast
from mytable
where cast(created_date as date) <= '02/28/2020';
ORA-01843: not a valid month
I have also tried to_date(created_date, 'MM/DD/YYYY')
in the from but proves to be erroneous with:
ORA-01858: a non-numeric character was found where a numeric was expected
Upvotes: 0
Views: 180
Reputation: 167774
Don't use CAST
and don't use TRUNC
(as then Oracle will not be able to use an index on your column but would, instead, require a function-based index created on TRUNC(created_date)
) just add a day and use a literal:
SELECT created_date
FROM mytable
WHERE created_date < DATE '2020-02-29';
or
SELECT created_date
FROM mytable
WHERE created_date < TIMESTAMP '2020-02-29 00:00:00';
or, if you want to specify the exact date then just add a day. E.g.:
SELECT created_date
FROM mytable
WHERE created_date < DATE '2020-02-28' + INTERVAL '1' DAY;
All of those options should be able to use an index on the created_date
column.
I have also tried
to_date(created_date, 'MM/DD/YYYY')
in the from but proves to be erroneous with:ORA-01858: a non-numeric character was found where a numeric was expected
TO_DATE( value_string, format_model )
takes strings as its arguments but CREATED_DATE
is a TIMESTAMP
data type and not a string so Oracle must make an implicit TIMESTAMP
-to-string conversion and it does this using the NLS_TIMESTAMP_FORMAT
session parameter; so your expression is effectively:
TO_DATE(
TO_CHAR(
created_date,
( SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_TIMESTAMP_FORMAT' )
),
'MM/DD/YYYY'
)
And if your NLS_TIMESTAMP_FORMAT
is not MM/DD/YYYY
then its highly likely that an exception will be raised (i.e. like the ORA-01858
you had).
You should never rely on implicit string conversions as any user can change their own session parameters at any time and an implicit conversion that works for one user may not work for another just because they have different parameter values (even though the queries are identical).
Upvotes: 1
Reputation: 65105
Firstly cast as date which converts a timestamp value to a date value, and then don't forget to add trunc()
function in order to include the boundry value (date'2020-02-28'
in this case) also as
where trunc(cast(created_date as date)) <= date'2020-02-28'
Upvotes: 1
Reputation: 1269443
Use a date literal:
cast(created_date as date) <= date '2020-02-28'
I would also recommend dispensing with the cast()
-- assuming that created_date
is correctly stored as a date
or timestamp
:
created_date < (date '2020-02-28' + interval '1' day)
Upvotes: 0