Reputation: 111
I just want to ask a simple question, I have a procedure in my package: procedure(p_x in default sysdate). However, when i try to use this p_x to do query in my procdure, i got nothing from my table. My assumption is p_x does not get value from sysdate and it is null. Why does this happen? How can I fix it?
Thanks in advance.
In Package:
Procedure M_m(p_x in default sysdate)
In Package Body:
Procedure M_m(p_x in default sysdate) as
cursor cur is select manager_id, manager_name,manger_department
from employ_table where trunc(EmploymentDate)=trunc(p_x);
r_cur cur%rowtype;
Begin
for r_cur in cur
loop
DBMS_OUTPUT.PUT_LINE(employ_table.manager_id || employ_table.manager_name
|| employ_table.manager_department);
end loop;
end;
Upvotes: 2
Views: 1847
Reputation: 16001
Currently (as of 18c) the default
or :=
clause in a PLSQL parameter specification behaves like a pre-12c default
clause in a table column definition. That is, the default value is only applied when the corresponding column is not specified at all.
If you define a table column as
somedate date default sysdate
then it will only be assigned the default value if the insert
statement does not mention column somedate
at all. If the insert
sets somedate
to null
then it will be null, regardless of any default. The same behaviour is true of PL/SQL parameters. An explicit null
value passed in overrides any default that you set for a parameter.
You will need to define a local constant along the lines of
k_x constant date := coalesce(p_x,sysdate);
and then have the rest of the procedure refer to that instead of the parameter.
In 12c we have default on null
for table columns, but in my opinion PL/SQL lags behind, as it has no equivalent syntax for parameter defaults. If you pass null
to a PL/SQL parameter, it respects that null
and not any default that you specified, as it has no on null
syntax option.
If you would like Oracle to extend PL/SQL parameter defaults along the same lines as table columns then consider voting for my suggestion here:
https://community.oracle.com/ideas/18189
Upvotes: 2
Reputation: 8361
I guess Wernfried is right, it depends on how exactly you call it. Just add a DBMS_OUTPUT.PUT_LINE(p_x)
immediately before the FOR
to verify the value of the variable:
CREATE TABLE employ_table AS SELECT * FROM scott.emp;
UPDATE employ_table SET hiredate=SYSDATE WHERE ename='SCOTT';
CREATE OR REPLACE PACKAGE P IS
PROCEDURE M_m(p_x IN DATE DEFAULT sysdate);
END;
/
CREATE OR REPLACE PACKAGE BODY p IS
PROCEDURE M_m(p_x IN DATE DEFAULT sysdate) IS
CURSOR cur IS
SELECT * FROM employ_table WHERE TRUNC(hiredate)=TRUNC(p_x);
BEGIN
DBMS_OUTPUT.PUT_LINE('p_x='||p_x);
FOR r_cur IN cur LOOP
DBMS_OUTPUT.PUT_LINE(r_cur.mgr);
END LOOP;
END M_m;
END P;
/
EXEC P.m_m(DATE '1980-12-17');
p_x=1980-12-17 00:00:00
7902
EXEC P.m_m();
p_x=2018-05-26 17:50:11
7566
EXEC P.m_m(NULL);
p_x=
Upvotes: 3