How to format a Date variable in PLSQL - syntax

I am new to PL/SQL and have this question.
I created a procedure with the following specification:
PROCEDURE runschedule (i_RunDate IN DATE)
this i_RunDate comes in a specific format, and I need to change it to this format:
'MM/dd/yyyy hh:mi:ss PM'
I couldn't find how to re-format a Date variable.

You need to use the TO_CHAR function. Here's an example:
SELECT TO_CHAR(CURRENT_TIMESTAMP, 'MM/DD/YYYY HH12:MI:SS AM') FROM dual;

The DATE has not especific format, a DATE is a DATE. When stored in the database column, date values include the time of day in seconds since midnight, and a DATE variable has the same, only that when in some point you show the variable is formatted. PL/SQL can convert the datatype of a value implicitly, for example, can convert the CHAR value '02-JUN-92' to a DATE value.. but I don't recommend you rely on this implicit conversiosn. I always use the explicit conversion.
For more on this topic, you could read this:
http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/datatypes.htm#i9118
In your case, if you want to format your DATE to log something, or to show in your UI or wathever in a different format, you need to assig it to a varchar variable as Justin said, something like this:
....
v_generated_run_date DATE;
v_var_date VARCHAR2(30);
BEGIN -- generate sysdate if required
IF (i_RunDate is null)
THEN
v_var_date:=TO_CHAR(sysdate, 'MM/DD/YYYY HH12:MI:SS AM');
ELSE
v_var_date:=TO_CHAR(i_RunDate,'MM/DD/YYYY HH12:MI:SS AM');
END IF;
pkgschedule.createschedule (v_var_date);
commit;
END runschedule;
END
Your createschedule procedure, in this case, will have a varchar2 parameter...

Related

ORA-01861: literal does not match format string not working with format in oracle

I am uploading the data in table like this 2016-10-17T00:00:00+05:30 and while fetching the data into variable I am using it like this V_FINALSRDATE := cur_r.FINAL_SR_DATE
So while executing it, I am getting the error as ORA-01861: literal does not match format string.
So I tried like this
V_FINALSRDATE := TO_DATE(cur_r.FINAL_SR_DATE,'dd-mm-yyyy');
Please suggest what needs to be changed and updated.
2016-10-17T00:00:00+05:30 does not match the format dd-mm-yyyy and it has a time zone so it will not work converting it to a date.
You should be storing it in a TIMESTAMP WITH TIME ZONE data type:
DECLARE
V_FINALSRDATE TIMESTAMP WITH TIME ZONE;
-- create a cur_r cursor with FINAL_SR_DATE column.
BEGIN
V_FINALSRDATE := TO_TIMESTAMP_TZ(cur_r.FINAL_SR_DATE,'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM');
END;
/
If you want to convert it to a DATE then you can use something like:
DECLARE
V_FINALSRDATE DATE;
-- create a cur_r cursor with FINAL_SR_DATE column.
BEGIN
V_FINALSRDATE := CAST(
TO_TIMESTAMP_TZ(cur_r.FINAL_SR_DATE,'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM')
-- AT TIME ZONE 'UTC' -- Optionally, convert the date to a common time zone.
AS DATE
);
END;
/
db<>fiddle here

How to get the current date time in plsql?

My Code:
DECLARE
BEGIN
-- outputs 06-DEC-18
dbms_output.put_line(sysdate);
-- also outputs 18-DEC-06
dbms_output.put_line(to_date(sysdate,'yyyy-mm-dd hh24:mi:ss'));
END;
/
The output only shows the date. I want to get also the time.
SYSDATE does have a time component. The first one outputs 06-DEC-18 because your session's parameter NLS_DATE_FORMAT is set to DD-MON-YY.
You have these options.
use TO_CHAR
dbms_output.put_line(TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss'));
Modify NLS_DATE_FORMAT to show time.
ALTER SESSION SET NLS_DATE_FORMAT='yyyy-mm-dd hh24:mi:ss';
BEGIN
dbms_output.put_line(SYSDATE);
END;
/
Or use SYSTIMESTAMP to show higher precision of time like milliseconds.
BEGIN
dbms_output.put_line(SYSTIMESTAMP);
END;
/
You can use SYSTIMESTAMP
SELECT SYSTIMESTAMP
FROM DUAL
To convert date type to string with some format use to_char
to_char(sysdate::timestamp, 'YYYY-MM-DD HH24:MI:SS')

Converting an Oracle Stored Procedure DATE Input Parameter

I am very new to Oracle and have a question about input parameters to a stored procedure. Basically its a stored procedure being called from an external system passing in a date formatted as MM/DD/YYYY.
Oracle doesn't seem to like the MM/DD/YYYY format as it gives me a "not a valid month" error. (I think it wants like a DD-MMM-YYYY?) whatever the default is.
is there a way to convert the date as it comes into the procedure without getting an error?
such as:
create procedure test_proc
(
v_input_date IN DATE := to_char(v_input_date, 'MM/DD/YYYY')
)
I know the above code likely makes no actual sense but hopefully it will convey what I'd like to do. The user would call the procedure something like
BEGIN
test_proc('01/01/2018')
END
You may try with ANSI type date 'yyyy-mm-dd' formatting like in the following sample :
SQL>create or replace procedure test_proc( v_input_date date ) is
v_diff int;
begin
v_diff := trunc(sysdate)-v_input_date;
dbms_output.put_line(v_diff||' days difference...');
end;
/
SQL> set serveroutput on;
SQL> begin
test_proc(date '2018-03-21');
end;
/
2 days difference...
Your problem is not in the procedure, it is in the code calling the procedure.
'01/01/2018' is not a date it is a string but your procedure expects a date; however, Oracle tries to be helpful and will implicitly try to convert the string to a date using the TO_DATE( string_value, format_model ) function. Since it does not have a specified format model, it will use the default format for a date which is the NLS_DATE_FORMAT session parameter and if this format mask does not match the format of the string then you will get an error.
(Note: session parameters are per-user-session and can be changed by each user so you should not rely on them being the same for each user or even the same between sessions for the same user!)
You can see the format of the NLS_DATE_FORMAT session parameter using the query:
SELECT VALUE
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER = 'NLS_DATE_FORMAT';
And your code to call the procedure is implicitly being converted to something like:
BEGIN
test_proc(
TO_DATE(
'01/01/2018',
( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
)
);
END;
To generate a date you should explicitly convert the string to a date either by:
Using an ANSI literal
BEGIN
test_proc( DATE '2018-01-01' );
END;
Or by specifying the format mask used in the conversion
BEGIN
test_proc( TO_DATE( '01/01/2018', 'MM/DD/YYYY' ) );
END;

PL/SQL insert date with procedure

I want to insert date in my dates table by passing date as ('19-JUN-1997') parameter to procedure. Could anyone give me an example how to do it? It seems that I am doing something wrong with trying to insert date by putting variable in TO_DATE(my_var).
SET SERVEROUTPUT ON
BEGIN
p_date('14-MAR-2017');
END;
CREATE OR REPLACE PROCEDURE p_date(
v_date IN Dates.date1%type) IS
BEGIN
INSERT INTO Dates
(date1)
VALUES
(TO_DATE(v_date ));
END;
If you know the format of the date (e.g., dd-mon-yyyy) then the safest thing to do is make your insert statement like thus:
INSERT INTO Dates (date1)
VALUES (TO_DATE(v_date, 'DD-MON-YYYY');
In order for your example to work, the character string date format must be in the default date format in the database. You can get the value of the database default format using this:
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_FORMAT'
However, if the default format is changed and you are relying on it, your code will break. It also tells the reader of the code what the date format you're expecting is.

Oracle Date Comparison Issue Totally confused - what am I doing wrong?

I am newbie & learning Oracle. I want to compare dates in function, while implementing the function I got an issue that output is wrong and not getting a valid answer I search a lot for a solution but in vain....
Solution so far I found was:
Do not compare Datetime to date.
If using DateTime, first TRUNC is needed to remove time factor.
While comparing date first convert dates to To_char(anyDate,'dd-mon-yyyy');
if we are comparing date like 1-dec-13 to 27-dec-13, make sure that both of the year are same. like both should be of 2013.
I have passed through all the constraints so far i found but fail to find the solution. Can any body help me. what blunder am i doing? Thanks in advance for anticipation.
SET serveroutput on;
DECLARE
startDate DATE := to_date('1'|| '/' ||to_char(sysdate, 'MM') || '/2013','DD/MM/YYYY');
secDate DATE :=to_date(SYSDATE, 'DD/MM/YYYY ');
BEGIN
DBMS_OUTPUT.PUT_LINE( 'if secDate '|| secDate ||' is Greater Then');
DBMS_OUTPUT.PUT_LINE( 'StartDate '|| startDate || ' Output = ' );
if(secDate>startDate)
then
DBMS_OUTPUT.PUT_LINE('True' );
else
DBMS_OUTPUT.PUT_LINE('false');
end if;
end;
Your points in order:
i An Oracle DATE holds date and time, accurate to the second. You can compare them, for example 12/27/2013 00:00:00 is less than 12/27/2013 09:00:00.
ii If you want to see if two DATE values with a time component (for example 12/27/2013 14:00:00 and 12/27/2013 12:34:56) are on the same day, then yes, you want TRUNC: IF TRUNC(firstDate) = TRUNC(secondDate).
iii There's nothing to be gained by using TO_CHAR for comparing DATE values. Use TRUNC if you don't want to include the time in the comparison; leave it out if you want the time.
iv The years don't have to be the same. A date like 12/27/2013 is greater than 12/27/2012 and less than 12/27/2014. If you leave it as a DATE type Oracle will do the right thing.
As for what's going wrong with your code, take a look at your startDate initialization:
'1'|| '-' ||to_char(sysdate, 'MM') || '2013'
For today, that will give you 1-122013, which doesn't match the format string DD/MM/YYYY in the TO_DATE call. That's why you're not getting a decent date.
If you want to get the first day of the current month, Oracle provides a convenient shortcut:
startDate := TRUNC(SYSDATE, 'MONTH');
So I'd forget about all the formatting and go with something like this; note how it's a lot simpler:
SET serveroutput on;
DECLARE
startDate DATE := TRUNC(SYSDATE, 'MONTH');
secDate DATE := SYSDATE;
BEGIN
DBMS_OUTPUT.PUT_LINE( 'if secDate '|| secDate ||' is Greater Then');
DBMS_OUTPUT.PUT_LINE( 'StartDate '|| startDate || ' Output = ' );
if(secDate>startDate) then
DBMS_OUTPUT.PUT_LINE('True' );
else
DBMS_OUTPUT.PUT_LINE('false');
end if;
END;
Note that secDate will be equal to startDate only at midnight on the first day of the month, when both values (for December 2013) will be 12/27/2013 00:00:00. At all other times of the month, secDate will be greater.
And note that I used 12/27/2013 00:00:00 to explain December 27, 2013 at midnight. That's just so I could explain the date in English. It's not how Oracle stores dates. How does Oracle store dates? It doesn't really matter - the important thing is that Oracle handles the date just fine if you leave it in DATE format and use TRUNC when you care only about the date and not about the time.
to_date(SYSDATE, 'DD/MM/YYYY ') that is your problem. It gives 27.12.0013 as a result. That is why you get false printed. Actually you don't need to convert sysdate to date as it is already of type date. Use this instead:
secDate DATE := SYSDATE;
See this line to_date('1'|| '-' ||to_char(sysdate, 'MM') || '2013','DD/MM/YYYY');
'1'|| '-' ||to_char(sysdate, 'MM') || '2013' gives you '1-122013', so you make
to_date('1-122013','DD/MM/YYYY');
The format don't match, you have to change one of them, either
to_date('01/'|| to_char(sysdate, 'MM')|| '/2013','DD/MM/YYYY');
or
to_date('01'|| '-' ||to_char(sysdate, 'MM')|| '2013','DD-MMYYYY')
Instead of secDate DATE :=to_date(SYSDATE, 'DD/MM/YYYY '); simply use secDate DATE :=TRUNC(SYSDATE);, there is no need for a conversion.

Resources