Oracle to_date function. Mask needed - oracle

I have string of date from xml file of such kind: '2010-09-09T22:33:44.OZ'
I need to extract only date and time. I want to ignore symbol T and .OZ (time zone). Which mask I should use? Thanks in advance

select TO_DATE('2010-09-09T22:33:44.OZ'
,'YYYY-MM-DD"T"HH24:MI:SS".OZ"')
from dual;
9/09/2010 10:33:44 PM

If the timezone information is needed:
select to_timestamp_tz('2010-09-09T22:33:44.GMT','YYYY-MM-DD"T"HH24:MI:SS.TZR')
from dual;
09-SEP-10 22.33.44.000000000 GMT
But OZ isn't a recognised timezone abbreviation, so you'd need to do some pre-conversion of that to something that is.
If you want to just ignore that part, and it's fixed, you can do what #Jeffrey Kemp said:
select to_date('2010-09-09T22:33:44.OZ','YYYY-MM-DD"T"HH24:MI:SS."OZ"')
from dual;
09/09/2010 22:33:44 -- assuming your NLS_DATE_FORMAT is DD/MM/YYYY HH24:MI:SS
If you want to ignore it but it isn't fixed then you'll need to trim it off first, something like (using a bind variable here for brevity):
var input varchar2(32);
exec :input := '2010-09-09T22:33:44.OZ';
select to_date(substr(:input,1,instr(:input,'.') - 1),'YYYY-MM-DD"T"HH24:MI:SS')
from dual;
09/09/2010 22:33:44

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

I have a varchar value 1st March 2017 that i need as a date 01-MAR-2017 in pl/sql

SELECT TO_DATE('1st March 2017','DD MON YYYY') from dual
It's ok with SELECT TO_DATE(01 March 2017','DD MON YYYY') from dual , doesn't like the 'st'
I think you need something like regex:
SELECT TO_DATE(
regexp_replace('1st March 2017','^(\d+)\w+','\1')
,'DD MON YYYY') from dual
Alas, you can't do it directly: https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#BABGDDFB
Notes on date format element suffixes:
When you add one of these suffixes to a datetime format element, the return value is always in English.
Datetime suffixes are valid only to format output. You cannot use them to insert a date into the database.
Which actually means they work only with to_char() to transform a date into a string; they don't work with to_date() to convert a string to a date.
So you will have to play dirty tricks - perhaps regexp_replace to get rid of st. Like Michael has shown already.
Hope here is your answer
SELECT to_date('1st march 2017','dd"st" month yyyy') "Date" FROM dual;
Date
01-MAR-17
SELECT TO_CHAR(to_date('1st march 2017','dd"st" month yyyy'),'dd-mon-yyyy') "Date"
FROM dual;
Date
01-mar-2017

date conversion from DD/MM/YYYY HH:MM:SS to YYYYMM

i want to convert date to some other format.
Below is the example 04/03/10 09:00:50.000000000 AMto YYYYMM
Iam not able to get this , below is the query which i used to convert.
select to_char(to_date('04/03/10 09:00:50.000000000 AM','MM/DD/YYYY HH:MM:SS AM'),'YYYYMM') from table;
Iam getting exception as below
ORA-01810: format code appears twice
01810. 00000 - "format code appears twice"
Format Code for Minutes is MI, not MM. MM is for months.
You are using 2-digit year. Better to use RR for this. Even better use 4-digit year.
TO_DATE doesn't store fractional seconds. You need to use TO_TIMESTAMP and use the FF as format code.
So, your query would be
select to_char(to_timestamp('04/03/10 09:00:50.000000000 AM','MM/DD/RR HH:MI:SS.FF9 AM'),'YYYYMM')
from table;
To achieve your goal there are many issues to resolve ;)
Finally I made this like that:
select to_char(
to_timestamp('04/03/10 09:00:50.000000000 AM','MM/DD/YYYY HH:MI:SS.FF9 PM',
'nls_date_language = ENGLISH'),
'YYYYMM') from dual;

SELECT * FROM T_TRANS WHERE TIME_START = to_date('01-09-2014', 'DD-MM-YY');

Sory, I have Question ? Why not show up when I execute some of its field content.
Please help me to fix it. Thank U
SELECT * FROM T_TRANS WHERE TIME_START = to_date('01-09-2014', 'DD-MM-YY');
Oracle is being a bit lenient with you with the date format mask, but you should use YYYY to make it clearer. But you're still providing a single point in time as midnight on that date:
select to_char(to_date('01-09-2014', 'DD-MM-YY'), 'YYYY-MM-DD HH24:MI:SS') as two_digit,
to_char(to_date('01-09-2014', 'DD-MM-YYYY'), 'YYYY-MM-DD HH24:MI:SS') as four_digit
from dual;
TWO_DIGIT FOUR_DIGIT
------------------- -------------------
2014-09-01 00:00:00 2014-09-01 00:00:00
Given the name of the column it's reasonable to assume you have other times, and your query won't match anything except exactly midnight. To find all records on that day, you need to provide a range:
SELECT * FROM T_TRANS
WHERE TIME_START >= to_date('01-09-2014', 'DD-MM-YYYY');
AND TIME_START < to_date('02-09-2014', 'DD-MM-YYYY');
... though I prefer the ANSI date notation for this sort of this:
WHERE TIME_START >= DATE '2014-09-01'
AND TIME_START < DATE '2014-09-02'
You could specify 23:59:59 on the same date, but that will break subtly when you use a timestamp field rather than a date field.
You could also truncate the value from the table (as #San said in a comment), or convert to a string for comparison (as #yammy showed in an answer), but either of those will prevent any index on the time_start column being used, affecting performance.
After reading Alex Poole suggestion, you should try:
SELECT * FROM T_TRANS WHERE to_char(TIME_START, 'DD-MM-YYYY') = '01-09-2014';
Shouldn't the format mask be "DD-MM-YYYY"?

Between 2 date/times in PL/SQL not giving expected answers

I have a query in PL/SQL on Oracle 10g that isn't behaving as I thought. I'm 100% sure I am doing something silly so I'm sorry.. Here goes:
I have some data in a table that looks like this:
I then went to query but using the time element, like this:
select * from dw_time
where createdtime > to_date('2012/04/12 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
When this is executed we get records returned that include the rows in the image 03:05AM. So thinking it was the to_date function I checked that:
select to_date('2012/04/12 10:24:00', 'yyyy/mm/dd hh:mi:ss')
from dual;
Now I was totally confused as it clearly know that as a time. So I tried it again:
select * from dw_time
where createdtime > to_date('2012/04/12 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
As you can see it is totally ignoring the time component! At this point I thought it was time to ask the gurus on here!
Many thanks
Mike
Is it possible that in your table '12/4/2012' means 4 Dec 2012 and query outputs it in MM/DD/YYYY format?
Look at DB output date format - it's MM/DD/YYYY - you can see it on output of:
select to_date('2012/04/12 10:24:00', 'yyyy/mm/dd hh:mi:ss') from dual;
So change your select to:
select * from dw_time where createdtime > to_date('2012/12/04 03:06:00', 'yyyy/mm/dd hh24:mi:ss')
You can see date output format by this query:
select * from nls_session_parameters where parameter = 'NLS_DATE_FORMAT';
And you can change date output format by this:
alter session set NLS_DATE_FORMAT='DD/MM/YYYY HH24:MI:SS';

Resources