带默认值sysdate的存储过程参数为null?原因及解决方法
问题原因与修复方案
核心原因
你遇到的问题本质是Oracle PL/SQL包中参数默认值的定义规则使用错误:
- 当在包规范(Package Specification)里为存储过程参数指定默认值后,包体(Package Body)中的对应参数绝对不能重复声明默认值。你的代码里包定义和包体都写了
p_x in default sysdate,这会导致调用存储过程时如果不传参数,p_x无法正确继承sysdate的默认值,反而被置为null——这就是查询无结果的直接原因,毕竟trunc(null)和任何trunc(EmploymentDate)都不匹配。 - 另外你代码里还有个小问题:
DBMS_OUTPUT.PUT_LINE里直接写employ_table.manager_id是错误的,应该用游标变量r_cur来引用字段,不然会触发编译错误或者输出异常值。
修复步骤
1. 修正参数默认值的定义
保留包规范中的默认值声明,包体里的参数列表去掉default sysdate,让包体继承包规范的参数默认值设置。
2. 修正游标循环的输出引用
把输出语句里的employ_table.xxx替换成r_cur.xxx,正确引用游标返回的行数据。
修正后的完整代码
包规范(Package Specification):
CREATE OR REPLACE PACKAGE your_pkg_name IS PROCEDURE M_m(p_x IN DATE DEFAULT SYSDATE); END your_pkg_name;
包体(Package Body):
CREATE OR REPLACE PACKAGE BODY your_pkg_name IS PROCEDURE M_m(p_x IN DATE) AS CURSOR cur IS SELECT manager_id, manager_name, manager_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(r_cur.manager_id || ' | ' || r_cur.manager_name || ' | ' || r_cur.manager_department); END LOOP; END M_m; END your_pkg_name;
验证说明
现在调用M_m()(不传参数)时,p_x会自动获取SYSDATE的默认值,TRUNC(p_x)会匹配employ_table中入职日期为当天的数据,就能正常输出结果了。如果需要指定日期调用,直接传参数即可,比如M_m(TO_DATE('2024-01-01', 'YYYY-MM-DD'))。
内容的提问来源于stack exchange,提问作者Crazymango
相关产品推荐
相关产品推荐

