Reputation: 225
I have a procedure.It takes date parameter with type Date.What i want to know is the other users send sysdate to my procedure.Which format they send sysdate to my procedure?
For example: 01/02/2021 or 01/02/2020 00:00:00(timestamp)
Does my procedure accepts all sending formats?Maybe Date type converts sending formats this style 01/02/2020.I am not sure.
I mean that does my Date parameter accepts all date formats because I want to use date in my procedure without seconds or minutes.
My procedure is
DECLARE
var_P_DATE DATE; (for example : 01/01/2021)
BEGIN
SELECT last_day(var_P_DATE) INTO v_last_day FROM DUAL; (31/01/2021)
if v_last_day = var_P_DATE (it returns false because no second or minutes)
.....
END;
I used DBMS.OUTPUT. I think Date type converts just like this 01/02/2021 and i do not get any error but i am not sure.
Upvotes: 2
Views: 751
Reputation: 191570
Your procedure will only ever receive a date
, because that is the data type of the formal parameter. When the procedure is called the caller can supply a date
, or something that can be implicitly converted to a date
(though they shouldn't; implicit conversions are generally a bad thing, particularly from strings).
The date
data type includes time components. If you are being passed a date with a non-midnight time that you want to ignore, such as sysdate
, you can use the trunc()
function, with it's default 'DD'
format; and you don't need to select from dual
:
v_last_day := last_day(trunc(var_P_DATE));
If the caller passes in systimestamp
then that will still be implcitly converted to a date
by the time you see it - which means it loses any fractional seconds and time zone information, but retains hours, minutes and seconds.
Dates and timestamps do not have have any inherent human-readable format. A date can be displayed using various formats - see the documentation - either explicitly with to_char()
and a format model, or implicitly using your session settings.
When you do
dbms_output.put_line(var_P_DATE);
you are doing an implicit conversion of the date
value to a string, using the session's NLS_DATE_FORMAT
setting. So, different users might see that in different formats. You have no control over that. If you want to see a specific format then specify that, e.g.:
dbms_output.put_line(to_char(var_P_DATE, 'YYYY-MM-DD'));
You also have no control over whether the caller sees that output - it's down to the application/client and its settings. It looks like you are probably only using it for debugging the comparison issue though, so that probably doesn't matter here.
So as a demonstration:
declare
var_P_DATE date := sysdate;
v_last_day date;
begin
v_last_day := last_day(var_P_DATE);
dbms_output.put_line(to_char(v_last_day, 'YYYY-MM-DD HH24:MI:SS'));
v_last_day := last_day(trunc(var_P_DATE));
dbms_output.put_line(to_char(v_last_day, 'YYYY-MM-DD HH24:MI:SS'));
end;
/
2021-02-28 09:59:02
2021-02-28 00:00:00
Upvotes: 3
Reputation: 22969
Date type in Oracle has hours, minutes and seconds, timestamp has fractions:
SQL> declare
2 vDate date := sysdate;
3 vTimeStamp timestamp := systimestamp;
4 begin
5 dbms_output.put_line('Date: ' || vDate);
6 dbms_output.put_line('Timestamp: ' || vTimestamp);
7 end;
8 /
Date: 2021-02-18 09:49:32
Timestamp: 18-FEB-21 09.49.32.015953 AM
If you want to use just the date part, with no time, of a date
variable, use something like trunc(vDate)
:
SQL> declare
2 vDate date := sysdate;
3 vTimeStamp timestamp := systimestamp;
4 begin
5 dbms_output.put_line('Date: ' || vDate);
6 dbms_output.put_line('Date truncated: ' || trunc(vDate));
7 dbms_output.put_line('Timestamp: ' || vTimestamp);
8 end;
9 /
Date: 2021-02-18 09:51:51
Date truncated: 2021-02-18 00:00:00
Timestamp: 18-FEB-21 09.51.51.024384 AM
An example of how comparison works on date
variables:
SQL> declare
2 vDate1 date;
3 vDate2 date;
4 begin
5 vDate1 := sysdate;
6 dbms_lock.sleep(5); /* wait 5 seconds */
7 vDate2 := sysdate;
8 --
9 if vDate1 = vDate2 then
10 dbms_output.put_line('Equal');
11 else
12 dbms_output.put_line('NOT equal');
13 end if;
14 --
15 if trunc(vDate1) = trunc(vDate2) then
16 dbms_output.put_line('Equal, truncated');
17 else
18 dbms_output.put_line('NOT equal, truncated');
19 end if;
20 end;
21 /
NOT equal
Equal, truncated
Upvotes: 1
Reputation: 65408
Just apply TRUNC()
function and use that variable of type DATE
within the procedure after defining the data type of var_P_DATE
as TIMESTAMP
CREATE OR REPLACE PROCEDURE myproc( var_P_DATE TIMESTAMP) AS
dt DATE := TRUNC(var_P_DATE) ;
BEGIN
...
...
END;
/
If you mean DBMS_OUTPUT.PUT_LINE
by DBMS.OUTPUT
, then that's completely irrelevant with your current conversion, that's just used to display result to the console as a string.
Upvotes: 1