SQL Navigator throws 'ORA-01834: Not a valid month' but query runs in other applications - oracle

I have stocked in this error many times but know I have no way to avoid and I have to get rid of it.
Sometimes I do run a query in SQL Navigator 6.1 XPert Edition and it throws:
ORA-01843: Not a valid month
But if I run this same query in same database but in other application(ie Aqua Data Studio) it works fine. It's just in isolated cases.
It may be some config problem?
EDIT: This query has that problem:
select
quantity dias_a_vencer
, estab
, initcap (planejador) planejador
, atributo2 fabrica
, mrp.item montagem
, initcap (descricao) des_montagem
, mrp.nro_docmto num_of
, initcap (mrp.fornecedor) cliente
, mrp.project_number projeto
, initcap (comprador) processista
, trunc (mrp.data_inicio) data_inicio
from etlt_mrp_exceptions mrp
where
mrp.compile_designator = 'ENGI'
and mrp.dt_coleta > sysdate - 50
and estab = '179' -- PARAMETRO ESTAB FILTRO
and atributo2 = '11' -- PARAMETRO FABRICA FILTRO
and nvl (mrp.quantity, 0) > 0
and dt_coleta = '05/12/2011' -- parametro do grafico acima
and initcap (planejador) = 'Maria Cristina Da Cruz Costa' -- parametro do grafico acima
order by quantity
, des_montagem

To make your query fail-safe in all environments, you have to change this line:
and dt_coleta = '05/12/2011'
to
and dt_coleta = to_date('05/12/2011', 'DD/MM/YYYY')
Assuming that you meant December 5th, and not May, 12th.
Btw: what datatype are the columns estab and atributo2. If those are numbers you should remove the single quotes around the parameters. That is another "implicit" data conversion that would e.g. prevent the usage of an index on those columns.

Always specify a date format, never assume it or use default formats. For example:
insert into mytable (mydate) values (to_date('02/28/2011', 'MM/DD/YYYY'));

Unfortunately, even using TO_DATE() does not guarantee success. (But I would strongly recommend that you are always aware of the date format in play.) For instance using SQL*Developer, this works:
alter session set nls_date_format='yyyy-mon-dd hh24:mi:ss.ddd';
select * from nns.nns_logGER WHERE LOG_DATE >= '2014-jul-30 14:47:16.211';
but this fails with "ORA-01834: day of month conflicts with Julian date" error:
alter session set nls_date_format='yyyy-mon-dd hh24:mi:ss.ddd';
select * from nns.nns_logGER WHERE LOG_DATE >= '2014-jul-30 14:47:16.210';
Notice that I changed only the last digit. And using to_date did not help:
select * from nns.nns_logGER WHERE LOG_DATE >=
to_date('2014-jul-30 14:47:16.210','yyyy-mon-dd hh24:mi:ss.ddd');
fails in the same way.
I wish there were better news, but I think this must be some internal problem.

Related

Trying to establish a trigger that counts rows after every update

I have two tables: SKN_ENJIN, and SKN_ENJIN_COUNT
SKN_ENJIN keeps track of usernames and emails.
SKN_ENJIN_COUNT is being used to populate a chart for a dashboard report.
I created this trigger earlier today:
create or replace trigger "BI_SKN_ENJIN_COUNT_TG"
after insert or update or delete on "SKN_ENJIN"
DECLARE
mCount NUMBER;
mDate DATE;
begin
select COUNT(ID) into mCount from SKN_ENJIN where Status = 1;
select TO_DATE(CURRENT_DATE, 'DD-MM-YYYY') into mDate from dual;
MERGE INTO SKN_ENJIN_COUNT c
USING dual d
ON (c.Count_date = mDate)
WHEN MATCHED THEN
UPDATE SET c.Member_count = mCount
WHEN NOT MATCHED THEN
INSERT (Count_date, Member_count)
VALUES (mDate, mCount);
end;
Up until about 10 minutes ago, the trigger worked beautifully. Suddenly, the trigger started throwing ORA-01843: not a valid month
I have tried changing CURRENT_DATE to SYSDATE(), I have tried changing TO_DATE to TO_CHAR. These approaches seemed to cause more errors to appear. What am I missing, and what should I change to solve this problem?
There's no need to call TO_DATE on CURRENT_DATE or SYSDATE. These functions already return DATEs, so there's no need to do any conversion.
In fact, calling TO_DATE on something that is already a DATE forces Oracle to convert it to a string using NLS settings (NLS_DATE_FORMAT) and the convert it back to a date using a given date format picture. If the date format picture you are using does not match NLS_DATE_FORMAT, you will likely end up with errors or incorrect values.
Instead of writing
select TO_DATE(CURRENT_DATE, 'DD-MM-YYYY') into mDate from dual;
you can write
select CURRENT_DATE into mDate from dual;
or just
mDate := CURRENT_DATE;
I don't know what type of the Count_date column in your SKN_ENJIN_COUNT table is, but if it is DATE, it is similarly incorrect to call TO_DATE on it.
I think I found a solution while stumbling my way through it
. It seems that the format of the date is extremely important. Earlier my formatting had been DD-MM-YYYY, when I used MM-DD-YYYY and just a touch of refactoring (ON (TO_DATE(c.Count_date, 'MM-DD-YYYY') = TO_DATE(mDate, 'MM-DD-YYYY')) the script worked without a fuss.
select COUNT(ID) into mCount from SKN_ENJIN where Status = 1;
select sysdate into mDate from dual;
MERGE INTO SKN_ENJIN_COUNT c
USING dual d
ON (TO_DATE(c.Count_date, 'MM-DD-YYYY') = TO_DATE(mDate, 'MM-DD-YYYY'))
WHEN MATCHED THEN
UPDATE SET c.Member_count = mCount

Oracle date comparison using to_date not working

I am using Oracle XE on my machine.
Defined a table as :
Name Type
ENAME VARCHAR2(20)
DOJ DATE
Firing a simple select:
select * from test1.tasty1;
ENAME DOJ
sat 08-DEC-16
So ok - I am aware that DATE field has time component in it.
The following query using TRUNC works fine:
select * from test1.tasty1 where trunc(DOJ) = '08-DEC-16';
Now I wanted to test the 'to_date' function - but none of the below queries worked - wonder why ?
select * from test1.tasty1 where DOJ =
to_date('08-12-2016','DD-MM-YYYY');
select * from test1.tasty1 where
DOJ = to_date('08-DEC-2016','DD-MON-YYYY');
select * from
test1.tasty1 where DOJ = to_date('08-DEC-16','DD-MON-YY');
select
* from test1.tasty1 where DOJ = to_date('08-DEC-16','dd-mon-RR');
Had taken a look at the following on SO:
Oracle TO_DATE not working
so not sure what is wrong here ?
From your question and comments, it appears that this is the sequence of events which happened.
You did the following INSERT into your table:
INSERT INTO test1.tasty1 VALUES ('sat', SYSDATE)
Keep in mind that dates in Oracle have both a date and a time component. So even though you did insert the date '2016-12-08' you also inserted a time component. As a result, the following query is not returning any records:
SELECT * FROM test1.tasty1 WHERE DOJ = '2016-08-12'
This is probably because you never specified the time component, and therefore the record you inserted earlier is not matching. If you want to compare only the date portion, you can use TRUNC as follows:
SELECT * FROM test1.tasty1 WHERE TRUNC(DOJ) = '2016-08-12'
The solution to your problem moving forward would be to wrap SYSDATE with TRUNC during the insert, if you really only want to deal with the date components.
By the way, the format '08-DEC-16' used as a literal will not be recognized by Oracle as a valid date. Instead, use '2016-12-08'.
Have you tried like this as comparison of date with date is correct:
select * from test1.tasty1 where to_date(DOJ,'DD-MM-YYYY') = to_date('08-12-2016','DD-MM-YYYY');
Compare apples with apples and not with mangoes.
What it worked from is instead of make a date to compare, change the date column to char with to_char(datecol, 'DD-MM-YYYY') = '01-01-2022'

compare 13digit (millisecond) unix timestamp with date in oracle

A database column (VARCHAR2 datatype) stores the date/time as 13 digit (milliseconds
) unixtimestamp format. Now when I want to compare the column with a oracle date (in question), The error thrown as 'invalid number'
I tried both ways,
converting the 13digit number to Date and compare with the date in question like below. The expressions seems valid as they are printed in select query, but if i include in the where part, it throws 'invalid number'
Here 'value' is 13th digit unixtimestamp column of VARCHAR2 datatype.
select
TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000,
TO_DATE('2014-04-21', 'YYYY-MM-DD')
from dummytable
-- where and TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000 > TO_DATE('2014-04-21', 'YYYY-MM-DD')
converting the date in question to 13digit unixtimestamp and comparing with the database column.The expressions seems valid as they are printed in select query, but if i include in the where part, it throws 'invalid number'
.
select
value,
(to_date('2013-04-21', 'YYYY-MM-DD') - to_date('1970-01-01', 'YYYY-MM-DD')) * (1000*24*60*60)
from dummytable
-- where value > ((to_date('2013-04-21', 'YYYY-MM-DD') - to_date('1970-01-01', 'YYYY-MM-DD')) * (1000*24*60*60))
any pointers? Thanks in advance.
[EDIT- 1 day later] I see the problem now. There are some data (other rows) for the 'value' column that are non-numeric. But I have another column say field, where always field='date' return value as 13 digit timestamp. Now I think when 'where' condition executes, although the field='date' is in the condition, it is still validating the other values for 'value' which are non-numeric. Is there a way to avoid this ?
Your code works just fine. The problem is in your data. Some of your values is not a number.
create table test
(value varchar2(13));
insert into test(value) values('2154534689000');
--insert into test(value) values('2 54534689000');
select TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000
from test
where TO_DATE('1970-01-01', 'YYYY-MM-DD') + value/86400000 > TO_DATE('2014-04-21', 'YYYY-MM-DD');
This code works fine. But if you uncommented the second insert, you would get exactly the same invalid number error as you get.
UPD. Allan gave you a nice hint, but i feel that it can be good to explain you a bit about views. The fact that you select from a view CAN make a difference. A view is not stored somewhere physically, when you select from it, it is just "added to your query". And then Oracle Query Optimizer starts working. Among other things, it can change the order in which your where predicates are evaluated.
For example, your the view query can have a line where value is not null and it would normally show only 'good' values. But if your query has a predicate where to_date(value,'ddmmyyyy') > sysdate, Oracle can decide to evaluate your predicate earlier, because Oracle predicts that it would "cut off" more rows, thus making the whole query faster and less momery consuming. Of course, execution will crash because of an attempt to convert a null string to date.
I believe, that Allan in his answer that he gave a link to, gave a great way to solve this problem: "wrapping" your query in a subquery that Oracle can't "unwrap":
select value
from
(select value
from my_view
where rownum > 0)
where to_date(value,'ddmmyyyy') > sysdate
Hope that helps.

Max Timestamp not giving correct result

I have a simple code to display latest error msg based on timestamp:
SELECT
line_item || ': ' || error_msg as RejectionMsg
FROM reqs
WHERE reqs_number = 'XXXXXXX'
and rqj_timestamp = (select max(rqj_timestamp) from reqs
WHERE reqs_number = 'XXXXXX' )
My data is something like :
rqj_timestamp line_item Error_msg
08-MAY-2009 14:00:04 8928 INVALID (RC4C) E
08-MAY-2009 14:00:04 8929 INVALID (R4CO) EY0
05-AUG-2013 00:13:42 11760 OO_USR_1 - NO_DATA_FOUND:No Data found for REQUEST
05-AUG-2013 00:13:42 11761 OO_USR_1 - NO_DATA_FOUND:No Data found for REQUEST
05-AUG-2013 00:13:42 11762 OO_USR_1 - NO_DATA_FOUND:No Data found for REQUEST
05-AUG-2013 00:14:59 11763 OO_USR_1 - NO_DATA_FOUND:No Data found for REQUEST
06-AUG-2013 06:55:59 11807 OO_45_ERROR_REGION_DERIV
06-AUG-2013 06:55:59 11808 OO_45_ERROR_REGION_DERIV
06-AUG-2013 06:55:59 11809 OO_45_ERROR_REGION_DERIV
My query is giving me output for 08-MAY-2009 14:00:04 time-stamp instead of the 06-AUG-2013 06:55:59 time-stamp.
3: INVALID (RC4C) E
3: INVALID (R4CO) EY0
Any idea where I am going wrong in this?OR how i can improve my query.. if i remove 08-MAY-2009 14:00:04 rows, it works perfectly fine.
Thanks in advance for help.
I would assuem your timestamp is not a date or similar data type, but a character data type like nvarchar2. Change you table to the proper data type.
A working but less clean solution would be to use something like
cast((select max(cast(rqj_timestamp as date)) from reqs) as nvarchar2)
which might depend on national language settings etc.
You would use the character data type that the column has in the outer cast.
Try something like (untested):
select *
from (
select r.*,
row_number() over (partition by reqs_number order by rqj_timestamp desc nulls last) rnum
from reqs r
where reqs_number = 'XXXXXXX'
)
where rnum = 1;
Also, the assumption is the "rqj_timestamp" is actually a timestamp (or at least a date).
Thanks for pointing out to check the datatype..turns out it was varchar, adding to_date(rqj_timestamp,'DD-MON-YYYY HH24:MI:SS') worked.

SSRS - Oracle DB, Passing Date parameter

Using SSRS with an Oracle Database. I need to prompt the user when running the report to enter a date for report. What is the best way to add in the parameter in my SSRS Report. Having problem finding the right date format. under the "Report Parameter" menu, I have setup the Report Parameters using the DateTime Datatype.
Keep getting this error "ORA-01843: Not a Valid Month"
Thank you for your help.
Select
a.OPR_Name,
a.OPR,
a.Trans_Desc,
a.Trans_Start_Date,
Cast(a.S_Date as date) as S_Date,
Sum(a.Duration) as T
From (
Select
US_F.OPR_Name,
ITH_F.OPR,
ITH_F.ITH_RID,
ITH_F.TRANSACT,
Transact.DESC_1 as Trans_Desc,
To_CHAR(ITH_F.Start_Time,'DD-Mon-YY') as Trans_Start_Date,
To_CHAR(ITH_F.Start_Time,'MM/DD/YYYY') as S_Date,
Substr(To_CHAR(ITH_F.Start_Time,'HH24:MI'),1,6) as Start_Time,
To_CHAR(ITH_F.End_Time,'DD-Mon-YY') as Trans_End_Date,
Substr(To_CHAR(ITH_F.End_Time,'HH24:MI'),1,6) as End_Time,
Cast(Case When To_CHAR(ITH_F.Start_Time,'DD-Mon-YY') = To_CHAR(ITH_F.End_Time,'DD-Mon-YY')
Then (((To_CHAR(ITH_F.End_Time,'SSSSS') - To_CHAR(ITH_F.Start_Time,'SSSSS')) / 60))/60
Else ((86399 - (To_CHAR(ITH_F.Start_Time,'SSSSS')) + To_CHAR(ITH_F.End_Time,'SSSSS'))/60)/60
End as Decimal(3,1)) as Duration
from Elite_76_W1.ITH_F
Left Join Elite_76_W1.Transact
on Transact.Transact = ITH_F.Transact
Left Join Elite_76_W1.US_F
on US_F.OPR = ITH_F.OPR
Where ITH_F.TRANSACT not in ('ASN','QC','LGOT')
) a
Where a.S_Date = #Event_Date
Having Sum(a.Duration) <> 0
Group By a.OPR_Name,
a.OPR,
a.Trans_Desc,
a.Trans_Start_Date,
a.S_Date
Order by a.OPR_Name
Oracle parameters are indicated with a leading colon - #Event_Date should be :Event_Date.
You use CAST(a.S_Date AS DATE) in your query, where a.S_Date is a VARCHAR: To_CHAR(ITH_F.Start_Time, 'MM/DD/YYYY'). If your session date parameter NLS_DATE_FORMAT is different from 'MM/DD/YYYY', this will result in a format error (in your case I suspect your NLS_DATE_FORMAT is something like DD-MON-YYYY, resulting in a "month" error).
A few options:
don't use TO_CHAR in the inner query (always try to keep the date format for internal calculations, use TO_CHAR only where it belongs -- in the GUI). If you only want the date portion, use TRUNC.
use TO_DATE instead of CAST in the outer query: to_date(a.S_Date, 'MM/DD/YYYY'), this is obviously tedious: you cast a date to a varchar that is later transformed to a date.

Resources