Oracle date comparison using to_date not working - oracle

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'

Related

How do I separate the time and date in SQL navigator?

I am trying to separate the time and date in one column to be independent off each other. I am new at writing scripts
this is my query:
select
*
from
[tablename]
where
to_date([column_name]) in ( '15-Jun-2021', '16-Jun-2021' )
and
to_char([column_name],'dd-Mon-yyyy HH:MM:ss') < '15-Jun-2021 19:54:30'
The way you put it, it would be
select *
from your_table
where date_column >= date '2021-06-15'
and date_column < to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss')
because
date_column should be of date datatype. If it isn't, you'll have problems of many kinds in the future. Therefore,
don't to_date it, it is already a date
don't to_char it either, because you'd be comparing strings and get unexpected result. Use that function when you want to nicely display the result
the second condition you wrote makes the first one questionable. If date_column is less than value you wrote, then you can omit date '2021-06-16' from the first condition because you won't get any rows for that date anyway
date literal (date '2021-06-15') sets time to midnight, so condition I wrote should return rows you want
SQL> select date '2021-06-15' first,
2 to_date('15.06.2021 19:54:30', 'dd.mm.yyyy hh24:mi:ss') second
3 from dual;
FIRST SECOND
------------------- -------------------
15.06.2021 00:00:00 15.06.2021 19:54:30
SQL>

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

The between and like functions with dates

I ran these two scripts below and they give two different results. The first did not include data for the 30th of April but the latter does. I am using oracle sql. Could someone assist?
select distinct * from a where (m_date between'01-MAY-17' AND '30-MAY-17');
select distinct * from a where m_date like '%-MAY-17';
I used the to_date function and it worked:
select distinct * from a where to_date (m_date) between'01-MAY-17' AND '30-MAY-17'
This produced the same results as with the like clause:
select distinct * from a where m_date like '%-MAY-17'
Your between clause
select distinct * from a where to_date (m_date) between'01-MAY-17' AND '30-MAY-17'
is the same as saying (pseudo-code)
...where to_date (m_date) between '01-may-17 00:00:00' AND '30-may-17 00:00:00'...
which excludes and date values on 5/30 where there is any time element other than 12AM in the morning. (Also, May does have 31 days).
It would be more correct to do the following, assuming m_date is a date data type and assuming you want all values during the month of may.
... where m_date >= to_date('01-may-17') and m_date < to_date('01-jun-17')...

how to catch this 20140205101309 date format?

I wanna catch the date in my table which is written like this "20140205101309" I tried to get by many ways, but i was not able to catch it so how to modifiy my query to catch it ?
select * from my.DETAIL a where A.DATE
between to_DATE('YYYYMMDD hh24:mi:ss','28-dec-2013 12:00:00')
and to_date ('YYYYMMDD hh24:mi:ss','2-feb-2014 00:00:00');
thank you in advance
Make a.call_date a date before comparing:
select *
from operation.reject_detail a
where to_date(a.call_date, 'YYYYMMDDHHMISS') between
to_date('28-12-2013 12:00:00','DD-MM-YYYY HH24:MI:SS') and
to_date('02-02-2014 00:00:00','DD-MM-YYYY HH24:MI:SS' );
Assuming 20140205101309 is: 2014, februari, 5 10:13:09
If you are not interested in the time part do this:
select *
from operation.reject_detail a
where to_date(substr(a.call_date,1,8), 'YYYYMMDD') between
to_date('28-12-2013','DD-MM-YYYY') and
to_date('02-02-2014','DD-MM-YYYY');
Storing dates as strings is bad practice, but since that is what you have and it's in a relatively sensible format, you can just compare it as a string:
select * from my.DETAIL a
where A.DATE between '20131228120000' and '20140202000000'
Or to ignore the time part on the table and include the full second date:
select * from my.DETAIL a
where A.DATE between '20131228000000' and '20140202235959'
There doesn't seem to be much point converting everything to DATE types, particularly if your column is indexed. If it isn't indexed than you could just look at the date part:
where substr(A.DATE, 1, 8) between '20131228' and '20140202'

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

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.

Resources