extract month and year in oracle - oracle

Why does below query work successfully?
select to_char(sysdate,'MM-YYYY') from dual;
But the following queries give an invalid number error:
select to_char('28-JUL-17','MM-YYYY') from dual;
select to_char('7/28/2017','MM-YYYY') from dual;
Though, below query gives you the same date format.
select sysdate from dual; -- 7/28/2017 11:29:01 AM

TO_CHAR function accepts only date or number. Maybe you can try this
select to_char(to_date('28-JUL-17', 'DD-MON-YY'),'MM-YYYY') from dual;

As a side note, if you're planning to convert a bunch of dates to strings so you can look for all records in a certain month of a certain year, be aware that the TRUNC function can be used to reduce the precision of a date (e.g. to "month and year"). The following query pulls all records created this month, from the table. It should be faster than converting dates to char and doing string comparison..
SELECT * FROM table WHERE trunc(create_date, 'MON') = trunc(sysdate, 'MON')

Because function TO_CHAR() accepts date or timestamp values. However, neither '28-JUL-17' nor '7/28/2017' are dates or timestamps - they are STRINGS.
Oracle gently tries to convert these stings into DATE values. This implicit conversion may work or may fail, it depends on your current session NLS_DATE_FORMAT, resp. NLS_TIMESTAMP_FORMAT settings.
As given already in other answers you have to convert the string explicitly:
TO_DATE('28-JUL-17', 'DD-MON-RR')
TO_DATE('7/28/2017', 'MM/DD/YYYY')

to_char() isn't expecting you to start with a char value. If you really want that to work, you'll need to wrap it around a to_date() function.
to_char(
to_date(
'28-JUL-17'
, 'DD-Mon-YY'
)
,'MM-YYYY'
)

You are using an incorrect mask, for more information read here.
The correct one should be:
select to_char(to_date('28-JUL-17','DD-MON-YY'), 'MON-YY') from dual;
You can also extract the month using EXTRACT:
select EXTRACT (MONTH FROM to_date('28-JUL-17','DD-MON-YY')) from dual;
Cheers

Related

Fetch Hours from Created date

I'm just trying to fetch Hour of my table from created date in Oracle 12c Database but it is showing error INVALID EXTRACT FIELD FOR EXTRACT FIELD. kindly guide me to fetch hour of my date my code is here...
SELECT
EXTRACT( HOUR FROM (TO_CHAR(CREATED_DATE,'RRRR-MM-DD HH:MI:SS')) ) HOUR
FROM
INVOICE_V;
my Date is stored as 6/1/2020 4:04:50 PM in this format and Extract function is not accept this function.
Do not store dates as strings.
But, since you have, convert it from a string to a date using TO_DATE:
SELECT EXTRACT( HOUR FROM TO_TIMESTAMP(CREATED_DATE,'DD/MM/YYYY HH12:MI:SS AM') ) AS HOUR
FROM INVOICE_V;
If, however, you meant that its just displaying in that format (and is actually a DATE data type) then CAST the date to a timestamp:
SELECT EXTRACT( HOUR FROM CAST( CREATED_DATE AS TIMESTAMP) ) AS HOUR
FROM INVOICE_V;
An hour can not be used in the EXTRACT function.
The only way to extract hour is to use TO_CHAR or subtract it from TRUNC date as follows:
TO_CHAR(created_date,'HH24') -- OR 'HH' as per your requirement
-- OR
FLOOR(24*(created_date- TRUNC(created_date)))
Please note that Oracle does not store dates in any format. It has its own binary representation. What you see while selecting from the table is based on the NLS_DATE_FORMAT parameter.
You can set it according to your requirement.
ALTER SESSION SET NLS_dATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; -- like this
If you have a date column (or the-like), then:
select extract(hour from cast(created_date as timestamp)) as hr
from invoice_v
Alternatively:
select to_char(created_date, 'hh24') as hr
from invoice_v
The first expression returns an integer number, while the second produces a string.
Note that hour is a language keyword, hence not a good choice for an identifier (here, you used it as a column alias). I changed that.

Invalid date format in datatype column in BODS job to Oracle

I am using SAP BODS and I am trying to fetch data from an ORACLE server using SQL query transormation. Now The table has a column named latest_changed_date which is a datetime column. I only want yesterday and current day data from that table. Now since the column is datetime, I need to convert it to date, but when I am using to_date function I get the following error.
SELECT *
FROM ABC.TEST
WHERE TO_DATE(LATEST_CHANGED_DATE) = TO_DATE(SYSDATE-1)
The database error message is
ORA-01843: not a valid month
I tried giving date format in TO_DATE condition as below:
SELECT *
FROM ABC.TEST
WHERE TO_DATE(LATEST_CHANGED_DATE,'YYYY-MM-DD') >= TO_DATE(SYSDATE-1,'YYYY-MM-DD')
Here I got the error:
date format picture ends before converting entire input string
I used trunc function also and again got either:
not a valid month
or
inconsistent datatypes: expected NUMBER got DATE
Below is a sample data for the column. I just need data for current and day before data from the column.
Update: I think the main issue is that I am not able to determine the proper datatype for the column in the source table and currently I don't have an option to determine that.
Rather than trying to implicitly cast your dates to strings and convert them back using TO_DATE( string_value, format_model ) you can use TRUNC() to truncate SYSDATE to the start of the day:
SELECT *
FROM ABC.TEST
WHERE LATEST_CHANGED_DATE >= TRUNC( SYSDATE-1 )
this will work:
SELECT *
FROM ABC.TEST
where sysdate-LATEST_CHANGED_DATE<=sysdate-(sysdate-2);
for example take this:
ALTER SESSION SET NLS_DATE_FORMAT = ' DD-MON-YYYY HH24:MI:SS';
SELECT * FROM d061_dates ;
03-DEC-2018 17:44:38
25-AUG-2018 17:44:42
30-AUG-2018 17:44:46
01-DEC-2018 17:44:49
02-DEC-2018 17:46:31
SELECT * FROM d061_dates
where sysdate-a<=sysdate-(sysdate-2);
03-DEC-2018 17:44:38
02-DEC-2018 17:46:31
you have to take sysdate minus on both sides to get comparision by a number which is less than equal to 2 to get day and day before yesterday and its giving the correct output.
thank you!!!!!!!!!!!!!

Oracle - Date comparison with SYSDATE

I need to compare date with date of current day, using SYSDATE, something like this:
SELECT * FROM my_table
WHERE date_column BETWEEN TO_DATE(SYSDATE -3,'dd.mm.yyyy') AND TO_DATE(SYSDATE,'dd.mm.yyyy');
However, this produces no result....My question :
Based on accepted answer here we should NEVER EVER compare strings with date. But in other side, a SYSDATE is allready a Date data type, and we should not compare It to a date - see here.
If I replace TO_DATE with TO_CHAR in upper SQL things go working again. But TO_CHAR function converts into String, so Oracle (I pressume) needs to convert this string again to date so you force Oracle to do an implicit data type conversion.
So, what should be a correct comparison with date and SYSDATE, in order to avoid Oracle working a bit slowly ?
You should not need to call either TO_DATE or TO_CHAR:
SELECT *
FROM my_table
WHERE date_column >= TRUNC(SYSDATE - 3) AND date_column < TRUNC(SYSDATE + 1);
Assuming date_column is a date type, you should be able to directly compare it against SYSDATE, or SYSDATE offset by some number of days.

Oracle date comparison in where clause

For eg I have a student table with a DOJ(date of joining) column with its type set as DATE now in that I have stored records in dd-mon-yy format.
I have an IN param at runtime with date passed as string and its in dd/mm/yyyy format. How do I compare and fetch results on date?
I want to fetch count of records of students who have DOJ of 25-AUG-92 per my database table student, but I am getting date as varchar in dd/mm/yyyy format in an IN param, kindly please guide.
I have tried multiple options such as trunc, to_date, to_char but, unfortunately nothing seems to work.
I have a student table with a DOJ(date of joining) column with its type set as DATE now in that I have stored records in dd-mon-yy format.
Not quite, the DATE data-type does not have a format; it is stored internally in tables as 7-bytes (year is 2 bytes and month, day, hour, minute and second are 1-byte each). The user interface you are using (i.e. SQL/PLUS, SQL Developer, Toad, etc.) will handle the formatting of a DATE from its binary format to a human readable format. In SQL/Plus (or SQL Developer) this format is based on the NLS_DATE_FORMAT session parameter.
If the DATE is input using only the day, month and year then the time component is (probably) going to be set to 00:00:00 (midnight).
I have an IN param at runtime with date passed as string or say varchar and its in dd/mm/yyyy format. How do I compare and fetch results on date.?
Assuming the time component for you DOJ column is always midnight then:
SELECT COUNT(*)
FROM students
WHERE doj = TO_DATE( your_param, 'dd/mm/yyyy' )
If it isn't always midnight then:
SELECT COUNT(*)
FROM students
WHERE TRUNC( doj ) = TO_DATE( your_param, 'dd/mm/yyyy' )
or:
SELECT COUNT(*)
FROM students
WHERE doj >= TO_DATE( your_param, 'dd/mm/yyyy' )
AND doj < TO_DATE( your_param, 'dd/mm/yyyy' ) + INTERVAL '1' DAY
The below should do what you've described. If not, provide more information on how "nothing seems to work".
-- Get the count of students with DOJ = 25-AUG-1992
SELECT COUNT(1)
FROM STUDENT
WHERE TRUNC(DOJ) = TO_DATE('25/AUG/1992','dd/mon/yyyy');
The above was pulled from this answer. You may want to look at the answer, because if performance is critical to you, there is a different way to write this query which doesn't use trunc, which will allow Oracle to use index on DOJ, if one is present.
Though I am bit late in posting this but I have been able to resolve this.
What I did was I converted both the dates to_char in similar formats and it worked here is my query condition that worked..
TO_CHAR(TO_DATE(C.DOB, 'DD-MON-YY'),'DD-MON-YY')=TO_CHAR(TO_DATE(P_Dob,'DD/MM/YYYY'),'DD-MON-YY'))
Thanks for the support all. :)

TO_DATE function in ORACLE

I was trying the TO_DATE function. Specifically, I noted that the following queries
1. SELECT TO_CHAR(TO_DATE('01-01-2015','DD-MM-YYYY'),'DD-MON-YY') FROM DUAL
2. SELECT TO_DATE('01-01-2015','DD-MM-YYYY') FROM DUAL
have the same output: 01-JAN-2015.
Why does the TO_DATE function return the month in its abbreviated form?
My expected output for the second query is something like 01-01-2015 (simply, a TYPE conversion, NOT a format conversion).
Am I wrong?
Thanks
Dates do not have a format - they are represented by 7- or 8-bytes.
SELECT DUMP( SYSDATE ) FROM DUAL;
Might output:
Typ=13 Len=8: 220,7,11,26,16,41,9,0
This format is very useful for computers to compare dates but not so useful to people; so, when the SQL client (SQL/plus, SQL Developers, TOAD, etc) displays a date it does not display the the bytes but displays it as a string.
It does this by making an implicit call to TO_CHAR() (or some other internal method of stringifying dates) and uses a default format mask to perform this conversion.
SQL/Plus and SQL Developer will use the user's session parameter NLS_DATE_FORMAT to perform this conversion - see this answer regarding this.
So your second query is implicitly being converted to do something approaching this (but, almost certainly, more efficiently):
SELECT TO_CHAR(
TO_DATE('01-01-2015','DD-MM-YYYY'),
( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
)
FROM DUAL
The default output format of DATE value, resp TO_DATE() function is set by NLS_DATE_FORMAT value. You can verify it with this query:
SELECT *
FROM V$NLS_PARAMETERS
WHERE PARAMETER = NLS_DATE_FORMAT';
You can change it on session level for example with
alter session set NLS_DATE_FORMAT = 'DD-MM-YYYY';
The output format of TO_CHAR is not correct, try:
SELECT TO_CHAR(TO_DATE('01-01-2015','DD-MM-YYYY'),'DD-MM-YYYY') FROM DUAL;
Oracle TO_DATE: is used to convert a character string to a date format.
and related to your concern; you need to alter your session like below:
alter session set nls_date_format='DD-MM-YYYY'
in your apps right after the connect.
So now if you run again your query :
SELECT TO_DATE ('01-01-2015', 'DD-MM-YYYY')
FROM DUAL;
the result would be as expected:
01-01-2015
Hope that will help.

Resources