Form the client I need to pass a SYSDATE argument to PL/SQL. In the server it need to be converted to date, for which iam using TO_DATE(in_timestamp, 'DD-MON-YYYY HH24:MI:SS'); What should be the data type of in_timestamp?
SYSDATE is itself a date, and it seems like the target field is also a date (Since you used TO_DATE()). Thus you don't actually need a conversion here.
Just pass SYSDATE and use it in your PL/SQL block, meaning in_timestamp should be a date.
As far as TO_DATE is concerned you can have CHAR, VARCHAR or VARCHAR2(recommended) basically it should be of String type as following examples suggest:-
to_date('2003/07/09', 'yyyy/mm/dd') would return a date value of July 9, 2003.
to_date('070903', 'MMDDYY') would return a date value of July 9, 2003.
to_date('20020315', 'yyyymmdd') would return a date value of Mar 15, 2002.
You can find more information related to TO_DATE at this link,
EDIT
*"However, if you are passing sysdate you dont't need to use TO_DATE again because it is already a Date value..."*as mentioned by #Gaurav and Hence the dataType of in_timestamp should be DATE..
Related
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.
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 am using Application Express (OracleXE 11g Express Edition installed on Win7 32-bit) on-line and the below stored procedure compiles and executes successfully with no errors. When compiling in SQL Plus command line, code compiles successfully, but when I execute, it gives me an error. Now I already solved the error (code snippet shown below), my question is why doesn't the database engine in Application Express throw an error ? Hope I am explaining my question correctly.
Table definition
CREATE TABLE DATE_DIMENSION
(
DATE_KEY DATE NOT NULL,
FULL_DATE_DESCRIPTION VARCHAR2(64) NOT NULL,
DAY_OF_WEEK NUMBER(1,0) NOT NULL,
DAY_OF_MONTH NUMBER(2,0) NOT NULL,
DAY_OF_YEAR NUMBER(3,0) NOT NULL,
LAST_DAY_OF_WEEK_INDICATOR CHAR(1) NOT NULL,
LAST_DAY_OF_MONTH_INDICATOR CHAR(1) NOT NULL,
WEEK_ENDING_DATE DATE NOT NULL,
MONTH_NUMBER NUMBER(2,0) NOT NULL,
MONTH_NAME VARCHAR2(32) NOT NULL,
YEAR_MONTH CHAR(32) NOT NULL,
QUARTER_NUMBER NUMBER(1,0) NOT NULL,
YEAR_QUARTER CHAR(32) NOT NULL,
YEAR_NUMBER NUMBER(4,0) NOT NULL,
CONSTRAINT DATE_DIMENSION_PK PRIMARY KEY (DATE_KEY)
)
/
Stored Procedure
create or replace PROCEDURE sp_DATE_DIMENSION(v_START_YEAR IN INT, v_END_YEAR IN INT) AS
--Declare two variables as DATE datatypes
v_CURRENT_DATE DATE;
v_END_DATE DATE;
BEGIN
--Assign the start year and end year to it's respective variables
v_CURRENT_DATE := TO_DATE('0101' || v_START_YEAR, 'MMDDYYYY');
v_END_DATE := TO_DATE('1231' || v_END_YEAR, 'MMDDYYYY');
--Clear/Dump what is currently stored in the table
DELETE FROM DATE_DIMENSION;
--Check the condition to see if the start year is less than the end year (Input Parameters)
WHILE v_CURRENT_DATE <= v_END_DATE
LOOP
--DATE_DIMENSION Table
INSERT INTO DATE_DIMENSION
(
DATE_KEY,
FULL_DATE_DESCRIPTION,
DAY_OF_WEEK,
DAY_OF_MONTH,
DAY_OF_YEAR,
LAST_DAY_OF_WEEK_INDICATOR,
LAST_DAY_OF_MONTH_INDICATOR,
WEEK_ENDING_DATE,
MONTH_NUMBER,
MONTH_NAME,
YEAR_MONTH,
QUARTER_NUMBER,
YEAR_QUARTER,
YEAR_NUMBER
)
VALUES
(
v_CURRENT_DATE, --DATE_KEY
TO_CHAR(v_CURRENT_DATE, 'Day, Month DD, YYYY'), --FULL_DATE_DESCRIPTION
TO_NUMBER(TO_CHAR(v_CURRENT_DATE, 'D')) -1, --DAY_OF_WEEK
TO_CHAR(v_CURRENT_DATE,'DD'), --DAY_OF_MONTH
TO_CHAR(v_CURRENT_DATE,'DDD'), --DAY_OF_YEAR
CASE --LAST_DAY_OF_WEEK_INDICATOR
WHEN TO_CHAR(v_CURRENT_DATE,'FMDay') = 'Saturday' THEN 'Y'
ELSE 'N'
END,
CASE --LAST_DAY_OF_MONTH_INDICATOR
WHEN LAST_DAY(TO_DATE(v_CURRENT_DATE, 'MM/DD/YYYY')) = TO_DATE(v_CURRENT_DATE, 'MM/DD/YYYY') THEN 'Y'
ELSE 'N'
END,
CASE --WEEK_ENDING_DATE OF CURRENT WEEK ENDING ON SATURDAY
WHEN TO_CHAR(v_CURRENT_DATE,'FMDay') = 'Saturday' THEN v_CURRENT_DATE
ELSE NEXT_DAY(v_CURRENT_DATE,'SATURDAY')
END,
TO_CHAR(v_CURRENT_DATE,'MM'), --MONTH_NUMBER
TO_CHAR(v_CURRENT_DATE,'MONTH'), --MONTH_NAME
TO_CHAR(v_CURRENT_DATE,'MONTH YYYY'), --YEAR_MONTH
TO_CHAR(v_CURRENT_DATE,'Q'), --QUARTER_NUMBER
TO_CHAR(v_CURRENT_DATE,'YYYY Q'), --YEAR_QUARTER
TO_CHAR(v_CURRENT_DATE,'YYYY') --YEAR_NUMBER
);
--Increment and assign the current date value to be re-evaluated
v_CURRENT_DATE := v_CURRENT_DATE + 1;
END LOOP;
END;
FYI - This piece of code solved my issue to make it execute using SQL Plus.
CASE --LAST_DAY_OF_MONTH_INDICATOR
WHEN LAST_DAY(v_CURRENT_DATE) = v_CURRENT_DATE THEN 'Y'
ELSE 'N'
END,
You're doing this:
WHEN LAST_DAY(TO_DATE(v_CURRENT_DATE, 'MM/DD/YYYY'))
= TO_DATE(v_CURRENT_DATE, 'MM/DD/YYYY') THEN 'Y'
But v_current_date is already a DATE type, so for both of those calls to to_date, you're really doing to_date(to_char(v_current_date), 'MM/DD/YYYY'), and the to_char is using your session NLS_DATE_FORMAT - which is presumably MM/DD/YYYY in Apex, but something else in SQL*Plus.
You haven't shown your actual error, so I'm speculating a little, but you're effectively doing something like:
to_date(to_char(v_current_date, 'DD/MM/YYYY'), 'MM/DD/YYYY')
That would work sometimes, but get an invalid month error if the day of the month is after the 12th, since it's transposing the month and day numbers. Or your NLS setting mat be using MON, which would get the same error as Oracle is quite forgiving about using names instead of month numbers. Or some other format which gives a different error - there are several you could hit.
Your fix, to just use WHEN LAST_DAY(v_CURRENT_DATE) = v_CURRENT_DATE, avoids both the explicit conversion to a date, and the implicit conversion from a date to string, so there is no impact from your NLS settings.
It sounds like you are saying that neither environment threw a compilation error but one environment threw a runtime error. I would guess in that case that you've written code that depends on environmental settings that are different in the two environments.
Looking at your LAST_DAY_OF_WEEK_INDICATOR, that is in fact what you did by passing a DATE to TO_DATE. Functionally, that doesn't make sense, to_date does not take a DATE as a parameter, it only accepts a VARCHAR2. When you call
TO_DATE(v_CURRENT_DATE, 'MM/DD/YYYY')
therefore, Oracle has to do a few things.
First, it implicitly casts v_current_date to a string. Because it is an implicit cast, it will use your session's NLS_DATE_FORMAT setting. Every session in a database may have a different NLS_DATE_FORMAT and the NLS_DATE_FORMAT for a single session can change over time so the behavior of this implicit cast is not known at compile time. If your NLS_DATE_FORMAT is DD-MON-RR, which is the default setting if you did an Oracle client install on an English language Windows machine, the string that is passed to to_date would be "20-FEB-15" (assuming you called the procedure today). If your NLS_DATE_FORMAT is DD/MM/YYYY, the string passed to to_date would be "20/02/2015".
Next, it calls to_date passing in the string that was just generated and the format mask that you specified. If you happen to be in a session where the NLS_DATE_FORMAT matches the format mask you passed to to_date, you'll get the same date back from to_date. If there is a mismatch, however, you may get an error (a string in the format DD-MON-YYYY will never convert to a valid date in the MM/DD/YYYY format) or you may get an unexpected result (a string in the format DD/MM/YYYY may convert to a valid date using the MM/DD/YYYY format mask but that date won't be the same one that you started with-- March 1 would be converted to January 3 for example).
If you want your code to run correctly regardless of the environment, avoid implicit casts.
My table has two DATE format attributes, however, when i try to insert value it throws an error: date format picture ends before converting entire input string.
Here is my attempted code:
insert into visit
values(123456, '19-JUN-13', '13-AUG-13 12:56 A.M.');
I think the problem is with 12:56 but Oracle documentation says date implies both date and time.
Perhaps you should check NLS_DATE_FORMAT and use the date string conforming the format.
Or you can use to_date function within the INSERT statement, like the following:
insert into visit
values(123456,
to_date('19-JUN-13', 'dd-mon-yy'),
to_date('13-AUG-13 12:56 A.M.', 'dd-mon-yyyy hh:mi A.M.'));
Additionally, Oracle DATE stores date and time information together.
you need to alter session
you can try before insert
sql : alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
What you're trying to insert is not a date, I think, but a string. You need to use to_date() function, like this:
insert into table t1 (id, date_field) values (1, to_date('20.06.2013', 'dd.mm.yyyy'));
I had this error today and discovered it was an incorrectly-formatted year...
select * from es_timeexpense where parsedate > to_date('12/3/2018', 'MM/dd/yyy')
Notice the year has only three 'y's. It should have 4.
Double-check your format.