Reputation: 427
I'm trying to make a very simple query and I'm getty crazy over it cause I keep getting this error:
ora-01847 day of month must be between 1 and last day of month
This is the query
select *
from TAB1 H
JOIN TAB2 D ON D.PAR2 = H.PAR1
where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate
and H.FIELD = 'TEST';
What's weird is that if I take any of the two AND clause away, it'll work flowless. It will also work if, instead of using the last AND clause to retrieve some record , I pass their id directly so I don't think it's a problem of date format or anything else.
Both D.DATE and H.FIELD are defined as VARCHAR2(255 CHAR)
Any head up?
EDIT: [Actual dates that are causing issues]
01/10/2017
01/10/2018
01/10/2018
01/10/2017
01/05/2023
01/05/2023
01/05/2023
01/05/2023
01/05/2023
01/10/2017
01/05/2018
01/02/2018
!!!> While scrolling down to get this samples, it gave me that error again. I can only guess that it happened once arrived at a row with a 'TEST' value in the column
EDIT:
select H.*
from TAB1 H
JOIN TAB2 D ON D.PAR2 = H.PAR1
where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate;
Will gave the same error. Eliminating the where clause or selecting everything will "solve" the problem though.
EDIT:
select ID as ID, null as ID_REF
from TAB1
where FIELD = 'TEST'
union all
select NULL as ID, ID_REF as ID_REF
from TAB2
where TO_DATE(DATE, 'dd-mm-yyyy') <> sysdate;
This, scrolling down (and allegedly reaching a record while the two conditions lik), will give the same error.
Upvotes: 0
Views: 258
Reputation: 146329
The message for ORA-01847
is
day of month must be between 1 and last day of month
So the obvious candidate is
> where TO_DATE(D.DATE, 'dd-mm-yyyy') <> sysdate
That is, you have values in D.DATE
which contain strings that can't be cast to a date, such as '32-05-2017'
. This is always a risk when we use a VARCHAR column to hold a date - or a number.
"I scroll through the result set, as soon as it load the 100+th results, it blows"
Yes, that was what my questions about fetching were driving at. Clearly you have duff data (non-dates) in the d.date
column: filtering on h.field
simply brought the duff to the top of the result set quicker than scrolling through the whole table did.
You can investigate the scale of the rot with a function like this:
create or replace function is_date
(p_date_str in varchar2
, p_date_fmt in varchar2 := 'dd-mm-yyyy' )
return varchar2
as
return_value varchar2(20);
l_date date;
begin
begin
l_date := to_date(p_date_str, p_dae_fmt);
return_value := 'DATE';
exception
when others then
return_value := 'NOT A DATE';
end;
return return_value;
end;
/
This query will return the records you need to ponder:
select d.id -- or whatever
, d.date
from tab2 d
where is_date(d.date) = 'NOT A DATE'
/
What you do next rather depends on the nature and quantity of the duffness you discover. That problem may well merit a new question.
Upvotes: 4