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.
Related
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
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. :)
I have to put in STIMING a time when I insert I use TO_DATE function but it give me date not time and it should be time.
This is the table and the code that i use
SQL> select * from shift;
SNO SNAME STIMING
---------- -------------------- ---------
121323 morning 01-APR-17
112232 evening 01-APR-17
665342 afternoon 01-APR-17
SQL> update shift
2 set STIMING= ('07:00:00 HH,MI,SS')
3 where SNO=121323;
set STIMING= ('07:00:00 HH,MI,SS')
*
ERROR at line 2:
ORA-01843: not a valid month
I have to put in STIMING a time
Oracle does not have a TIME datatype. The DATE data type is always stored internally as 7-bytes and is always composed of year (2-bytes) and month, day, hours, minutes and seconds (1-byte each).
You cannot not have a year, month or day component of a DATE.
If you want a time on its own then you will have to store it as a different data type or store the year/month/day and ignore that component.
When you are SELECTing the STIMING column it is not showing the time component. You can change this by changing the default date format which is set in the NLS_DATE_FORMAT session parameter.
You can review this parameter using:
SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT';
You can set this value within your current session using:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
(Note: this does not change the value for any other users.)
When you insert the date you can use:
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TO_DATE( '01-APR-2017 07:00' DD-MON-YYYY HH24:MI' ) )
Or, an ANSI TIMESTAMP literal (which will be implicitly cast to the DATE format of the column):
INSERT INTO shift ( SNO, SNAME, STIMING)
VALUES ( 121323, 'morning', TIMESTAMP '2017-04-01 07:00:00' )
I suggest you to avoid updates, change your insert part from to_date with no formatting param to to_date( colname, 'DD-MON-YY HH24:MI:SS')
I am learning oracle 11g. I need to create columns to store Year and Month in the following sample format:
Year: 2015
Month: 6
I saw Date Time data type which takes whole date only .Also Number type may allow invalid year and month. But I want them in the given form while avoiding invalid month and year. Please tell me how to fix it.thanks
Updates: is this okay for such inputs?
CREATE TABLE FOOBAR (YYYY DATE, MM DATE);
The best solution is to store dates in DATE columns. Oracle has some pretty neat date functions, and you'll find it easy to work with storing the first of the month in a single DATE column. Otherwise you'll find yourself constantly extracting elements from other dates or cluttering your code with TO_CHAR() and TO_DATE() calls. Find out more.
However, if you have a rigid requirement, you can use strong typing and check constraints to avoid invalid months:
CREATE TABLE FOOBAR (
YYYY number(4,0) not null
, MM number(2,0) not null
, constraint foobar_yyyy_ck check (yyyy != 0)
, constraint foobar_mm_ck check (mm between 1 and 12)
);
This won't do what you want because it will default the missing elements:
CREATE TABLE FOOBAR (YYYY DATE, MM DATE);
We can't store just a year or just a month in DATE columns.
Use the DATE data type..
and when perform insert operation onto your db.. use
TO_DATE ('November 13, 1992', 'MONTH DD, YYYY')
For input and output of dates, the standard Oracle date format is DD-MON-YY, as follows:
'13-NOV-92'
perform insert operation/query like this:
INSERT INTO table_name (name, created_at) VALUES
('ANDY', TO_DATE ('November 13, 1992', 'MONTH DD, YYYY'));
Here is link to the guide as well:
https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i1847
If you want to store month and year separately in the db you may use NUMBER & NUMBER(n)
https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i22289
Hope this helps..
I have a date type column in a table, where I store date along with time.
I want to query it by WHERE clause
I did it this way:
select *
from conference_hall_book
where to_date(end_time,'dd/mon/yyyy hh24:mi:ss') <= to_date('26/oct/2013 15:00:00','dd/mon/yyyy hh24:mi:ss')
But the result has 27/10/2013 8:00:00 AM also in end_time column.
Can any one help me finding the mistake?
The problem occurs because of
to_date(end_time,'dd/mon/yyyy hh24:mi:ss')
This is a wrong usage of the to_date function. To_date converts a string to a date.
When Oracle sees this expression, it will automatically convert the end_time value to a string, using the configured date format of your database/session. This format typically doesn't include the time part, so a date with the value of "27/10/2013 8:00:00 AM" will be converted to the string "27/10/2013" (if your database date format is dd/mm/yyyy).
Your to_date expression will then convert the string value "27/10/2013" back to a date. The resulting date value will be "27/10/2013 00:00:00", so you will have lost the time portion of your original date.
The simple and correct solution is to drop the to_date(end_time) expression and just use end_time. This will also ensure that if you have index on end_time, the query will be able to use that index.
select *
from conference_hall_book
where end_time <= to_date('26/oct/2013 15:00:00','dd/mon/yyyy hh24:mi:ss')