for rate in ( select tgt.carrier_code, tgt.tc_code, tgt.exp_date, (TO_date(src.eff_date,'DD/MM/RRRR HH24:MI:SS') - 1/(24*60*60)) eff_date from mira_rate
tgt, mira_rate_dummy src
where src.carrier_code=tgt.carrier_code and src.tc_code=tgt.tc_code)
loop
update mira_rate
set exp_date=to_date(rate.eff_date,'DD/MM/RRRR HH24:MI:SS')
end loop;
When i run this query I am getting Format error.
How to correct this? I treid giving diff to_date options it says some .
Pls suggest
Assuming the question title means you got ORA-01843: not a valid month, this is probably down to your unnecessary to_date() calls as a_horse_with_no_name suggested, but it depends on your NLS_DATE_FORMAT setting. It's easy enough to reproduce, but only by making an assumption about your environment:
alter session set nls_date_format = 'MM/DD/RRRR';
select to_date(eff_date, 'DD/MM/RRRR HH24:MI:SS') from (
select (to_date(sysdate, 'DD/MM/RRRR HH24:MI:SS') - 1/(24*60*60)) eff_date
from dual
);
which gives:
select (to_date(sysdate, 'DD/MM/RRRR HH24:MI:SS') - 1/(24*60*60)) eff_date
*
ERROR at line 2:
ORA-01843: not a valid month
or since the error's pointing to the inner select, just:
SQL> select to_date(sysdate, 'DD/MM/RRRR HH24:MI:SS') from dual;
select to_date(sysdate, 'DD/MM/RRRR HH24:MI:SS') from dual
*
ERROR at line 1:
ORA-01843: not a valid month
The issue is that you're doing an implicit conversion of your date; effectively:
select to_date(to_char(sysdate, 'MM/DD/RRRR'), 'DD/MM/RRRR HH24:MI:SS')
The implicit conversion renders that as 01/28/2013 (or with the time as well, if that's in your NLS date mask), and when you then try to convert that back to a date with mask DD/MM/RRRR ... it's trying to use '28' as the month, which is clearly invalid.
If your fields are already dates then your to_date() calls are pointless, confusing and in this case causing an error. You should be able to do:
for rate in (select tgt.carrier_code, tgt.tc_code, tgt.exp_date,
src.eff_date - interval '1' second as eff_date
from mira_rate tgt, mira_rate_dummy src
where src.carrier_code=tgt.carrier_code and src.tc_code=tgt.tc_code)
loop
update mira_rate
set exp_date = rate.eff_date;
end loop;
I changed your - 1/(24*60*60) to - interval '1' second because I find that clearer, but it has the same effect.
Your update doesn't have a where clause though, but since it was missing a ; that might have been lost in transcription.
Related
I want a SQL query to show the current date and time.
I have tried
SELECT CURRENT_TIMESTAMP; --"FROM keyword not found where expected"
SELECT GETDATE(); --"FROM keyword not found where expected"
SELECT GETUTCDATE(); --"FROM keyword not found where expected"
NOW(); -- Error report - Unknown Command
But none of them worked.
Requesting your help.
Thanks!
Oracle supports ANSI standard variables CURRENT_TIMESTAMP and CURRENT_DATE with mandatory FROM clause -
SELECT CURRENT_TIMESTAMP FROM DUAL;
SELECT CURRENT_DATE FROM DUAL;
Alternatively, You can use Oracle specific date variable SYSDATE also -
SELECT SYSDATE FROM DUAL;
Demo.
You probably want to handle the format of date/time fetched. For that you can use To_Char() function. Some of the options are:
Select
SYSDATE "DB_FORMAT_DATE",
To_Char(SYSDATE, 'dd-Month yyyy') "DATE_FORMAT_1",
To_Char(SYSDATE, 'dd.mm.yyyy') "DATE_FORMAT_1",
To_Char(SYSDATE, 'hh:mi:ss am') "TIME_FORMAT_1",
To_Char(SYSDATE, 'hh24:mi:ss') "TIME_FORMAT_2",
To_Char(SYSDATE, 'dd-Mon-yyyy hh24:mi:ss') "DATETIME_FORMAT_ANY"
From Dual
DB_FORMAT_DATE DATE_FORMAT_1 DATE_FORMAT_1 TIME_FORMAT_1 TIME_FORMAT_2 DATETIME_FORMAT_ANY
-------------- ----------------- ------------- ------------- ------------- --------------------
02-FEB-23 02-February 2023 02.02.2023 04:29:30 PM 16:29:30 02-Feb-2023 16:29:30
More about it here.
I need to filter a table for specific, accurate to the second, timeperiods.
Datatype is "TIMESTAMP (6)"
select *
from table
where trunc(load_date)<=to_date ('10.08.15 15:10:58', 'dd.mm.yy hh24:mi:ss')
and trunc(load_date)>=to_date ('10.08.15 15:11:08', 'dd.mm.yy hh24:mi:ss');
This is what if come to. But i seem to miss smt.
select *
from b_bis_donexa_delta_2
where trunc(load_date)=to_date ('10.08.15', 'dd.mm.yy');
This works perfectly fine. But scolling through the results isn't very efficient.
atm i get no results, but no error message.
but there IS at least one result. i even tried to swap those < = > randomly because i thought i lost my mind.
Doing trunc(load_date) truncates the time to midnight on that value's day (and also converts to a date, rather than a timestamp):
select systimestamp, trunc(systimestamp) from dual;
SYSTIMESTAMP TRUNC(SYSTIMESTAMP)
------------------------------------ -------------------
2019-09-10 12:53:54.400453000 +01:00 2019-09-10 00:00:00
Once you've truncated your load_date, that midnight time is not within your target range. In your second version you are comparing the truncated value with a time which is also at midnight, hence it now finding a match - but it may or may not be in your 10-second window (there's no way to tell), and also may prevent an index on that column being used - which is probably why it's slow.
Don't truncate; and I'd compare against the same data type:
select *
from table
where load_date >= to_timestamp ('10.08.15 15:10:58', 'dd.mm.yy hh24:mi:ss')
and load_date <= to_timestamp ('10.08.15 15:11:08', 'dd.mm.yy hh24:mi:ss');
or preferably using 4-digit years:
select *
from table
where load_date >= to_timestamp ('10.08.2015 15:10:58', 'dd.mm.yyyy hh24:mi:ss')
and load_date <= to_timestamp ('10.08.2015 15:11:08', 'dd.mm.yyyy hh24:mi:ss');
or even timestamp literals if these are fixed values:
select *
from table
where load_date >= timestamp '2015-08-10 15:10:58'
and load_date <= timestamp '2015-08-10 15:11:08';
Also check that you do really want both >= and <=; if you are getting multiple 10-second ranges then you may actually want >= and < to avoid the exact time appearing in two ranges.
I have to calculate time difference in minutes from current(sysdate) and modified time:-
to_date(to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
- to_date(to_char(modified, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
but problem is to_char returns proper time:-
to_char(whenmodified, 'YYYY-MM-DD HH24:MI:SS')
Outputs 2016-05-23 14:55:50
and to_date doesn’t show time:-
to_date(to_char(modified, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS')
Outputs: 2016-05-23
Please assist how I can get time difference by converting to_char to to_date.
NOTE:
I cant do sysdate-modified because both sysdate and modified gives date without time e.g 2016-05-23
Using to_char for sysdate or modified give date with time 2016-05-23 14:55:50
As we cant subtracts dates in to_char function I am again converting back them to to_date for getting time.
I am expecting:
2016-05-23 14:55:50 - 2016-05-23 14:53:50 = 2 min
I have to calculate time difference in minutes from current(sysdate) and modified time
Oracle Setup:
CREATE TABLE table_name ( modified DATE );
INSERT INTO table_name
SELECT TIMESTAMP '2016-05-23 14:20:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-23 00:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-05-01 00:00:00' FROM DUAL UNION ALL
SELECT TIMESTAMP '2016-01-01 00:00:00' FROM DUAL;
Query:
SELECT ( sysdate - modified ) * 24 * 60 AS minute_difference
FROM table_name;
Output:
MINUTE_DIFFERENCE
-----------------
3.66666667
863.666667
32543.6667
206783.667
And to address your comment that:
to_date doesn’t show time
A date always has a time component and never has a format internally to the database (it is represented by 7 or 8 bytes) - the formatting of a date is done by the client program that you use to access the database (and often the default is not to show the time component - however, the time component still exists).
You can change this either in the preferences of your client program or, if they don't use that to control it, by changing the NLS_DATE_FORMAT session parameter:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
select *
from employee
having to_date(date, 'DD/MM/YYYY HH24:MI:SS') = to_date('01/01/2012 10:00:00', 'DD/MM/YYYY HH24:MI:SS')
Column 'date' is a VARCHAR/STRING
as to_date doesnt work in HSQL, how can make the above query work in HSQL ??
TO_DATE does work with latest versions HSQLDB. You can use version 2.2.9 or future release versions.
But your query is wrong as indicated in comment by a_horse_with_no_name and needs WHERE instead of HAVING.
select *
from employee
where to_date(date, 'DD/MM/YYYY HH24:MI:SS') = to_date('01/01/2012 10:00:00', 'DD/MM/YYYY HH24:MI:SS')
In fact you can also simplify the query
select *
from employee
where to_date(date, 'DD/MM/YYYY HH24:MI:SS') = timestamp'2012-01-01 10:00:00'
I know it's an old thread, but it is the top google result so it is probably better to update it than start a new one - especially I have solved my problem. I had a massive problem with this query (hsqldb version 2.3.2) where my date is a string created in java and stored as a varchar in the database.
The to_date call doesn't work without a cast for me and the documentation was a bit vague on how to make the cast correctly (I thought the varchar cast needs to be done specifying the actual length while it doesn't seem to be the case.
select * from table2 where to_date(cast(timestamp as VARCHAR(254)), 'YYYY-MM-DD') > to_date('2015-09-02', 'YYYY-MM-DD')
notice the cast(xxx as VARCHAR(254)) there!
I am trying to execute the below query but getting this error:
to_date ora-01847 day of month must be between 1 and last day of month
query is to check overlaping of date and time in two different tables
table1 (emp_num1 number,start_date1 date,start_time1 varchar2,end_date1 date,end_time2 varchar2)
table2(emp_num2 number,start_date2 date,start_time2 varchar2,end_date2 date,end_time2 varchar2)
select *
from table1 t1
,table2 t2
where t1.emp_num 1 = t2.emp_num2
and to_timestamp(to_char(start_date1,'DD-MON-YYYY')||' '||NVL(start_time1,'00:00'),'DD-MON-YYYY HH24:MI')
between
to_timestamp(to_char(start_date2,'DD-MON-YYYY')||' '||NVL(start_time2,'00:00'),'DD-MON-YYYY HH24:MI')
and
to_timestamp(to_char(end_date2,'DD-MON-YYYY')||' '||NVL(end_time2,'00:00'),'DD-MON-YYYY HH24:MI')
or
to_timestamp(to_char(end_date1,'DD-MON-YYYY')||' '||NVL(end_time1,'00:00'),'DD-MON-YYYY HH24:MI')
between
to_timestamp(to_char(start_date2,'DD-MON-YYYY')||' '||NVL(start_time2,'00:00'),'DD-MON-YYYY HH24:MI')
and
to_timestamp(to_char(end_date2,'DD-MON-YYYY')||' '||NVL(end_time2,'00:00'),'DD-MON-YYYY HH24:MI')
the above query resulting the error:
to_date ora-01847 day of month must be between 1 and last day of month
I tried running query
select to_timestamp(to_char(start_date1,'DD-MON-YYYY')||' '||NVL(start_time1,'00:00'),'DD-MON-YYYY HH24:MI') from table1
no error is encountered.
To reproduce the error:
SELECT NVL(SYSDATE,'00:00')
FROM DUAL
ORA-01847: day of month must be between 1 and last day of month
The NVL() description says:
The arguments expr1 and expr2 can have any data type. If their data
types are different, then Oracle Database implicitly converts one to
the other. If they cannot be converted implicitly, then the database
returns an error. The implicit conversion is implemented as follows:
If expr1 is character data, then Oracle Database converts expr2 to the data type of expr1 before comparing them and returns VARCHAR2 in
the character set of expr1.
If expr1 is numeric, then Oracle Database determines which argument has the highest numeric precedence, implicitly converts the other
argument to that data type, and returns that data type.
So we can simplify the reproduce case:
SELECT TO_DATE('00:00')
FROM DUAL
Since you don't provide a format, it's assuming NLS_DATE_FORMAT, and thus the error: '00' is not a valid day.
(I don't really know what you're trying to do but you can try using pure date functions.)
Your formatting is need to be fixed. Here's your initial setup:
SELECT '07-MAR-2013' start_date -- char
, NULL start_time -- char
FROM dual
/
Final formatting - NO NVL required. But if you must then add NVL(start_time, '00:00'):
SELECT to_timestamp(start_date||' '||start_time, 'DD-MON-YYYY HH24:MI:SS') t_stamp
FROM
(
SELECT '07-MAR-2013' start_date -- char
, NVL(NULL, '00:00') start_time -- char - NVL is optional
FROM dual
)
/
3/7/2013 12:00:00.000000000 AM
You will get the same result if you remove start_time compl. Generally to compare dates you should use TRUNC to remove time portion.
SELECT to_timestamp('07-MAR-2013', 'DD-MON-YYYY HH24:MI:SS') start_date_only
FROM dual
/
3/7/2013 12:00:00.000000000 AM
SELECT trunc(to_timestamp('07-MAR-2013', 'DD-MON-YYYY HH24:MI:SS')) start_date_only FROM dual
/
3/7/2013