创建含双参数存储过程的Oracle包及解决调用报错问题
ORA-06550/PLS-00306错误解决:Oracle存储过程包的正确实现与调用
1. 正确的包定义与实现示例
假设你要查询的业务表为business_data,包含entity_id(实体ID)、record_date(记录日期)、value(数值)、description(描述)字段,以下是符合要求的包规范和包体:
包规范(PACKAGE)
CREATE OR REPLACE PACKAGE data_query_pkg IS -- 存储过程:接收日期、实体参数,返回匹配数据的游标 PROCEDURE get_matching_data( p_new_date IN DATE, p_new_entity IN VARCHAR2, p_result OUT SYS_REFCURSOR ); END data_query_pkg; /
包体(PACKAGE BODY)
CREATE OR REPLACE PACKAGE BODY data_query_pkg IS PROCEDURE get_matching_data( p_new_date IN DATE, p_new_entity IN VARCHAR2, p_result OUT SYS_REFCURSOR ) IS BEGIN OPEN p_result FOR SELECT entity_id, record_date, value, description FROM business_data WHERE record_date = p_new_date AND entity_id = p_new_entity; END get_matching_data; END data_query_pkg; /
2. 错误原因拆解
你遇到的两个错误本质关联:
- PLS-00306:调用存储过程时参数不匹配,常见场景:
- 漏传/多传参数(比如忘记传返回结果的OUT游标参数)
- 参数类型不兼容(比如直接传字符串给DATE类型参数,或参数顺序搞反)
- 参数长度超出定义范围(比如VARCHAR2参数传了比定义更长的字符串)
- ORA-06550:要么是调用语句语法错误,要么是包本身编译失败(先确认包的状态是否为VALID)
3. 正确调用示例
PL/SQL块调用
DECLARE v_result SYS_REFCURSOR; v_entity VARCHAR2(50); v_date DATE; v_value NUMBER; v_desc VARCHAR2(200); BEGIN -- 用命名参数调用,避免顺序错误 data_query_pkg.get_matching_data( p_new_date => TO_DATE('2024-05-20', 'YYYY-MM-DD'), p_new_entity => 'ENTITY_001', p_result => v_result ); -- 遍历游标输出数据 FETCH v_result INTO v_entity, v_date, v_value, v_desc; WHILE v_result%FOUND LOOP DBMS_OUTPUT.PUT_LINE('实体: ' || v_entity || ', 日期: ' || TO_CHAR(v_date, 'YYYY-MM-DD') || ', 值: ' || v_value); FETCH v_result INTO v_entity, v_date, v_value, v_desc; END LOOP; CLOSE v_result; END; /
图形化工具调用(比如SQL Developer)
- 确保绑定的参数类型与存储过程定义一致:DATE类型参数选择日期控件,不要直接输入字符串
- 不要遗漏OUT类型的游标参数,工具会自动处理游标结果的展示
4. 排查步骤
- 检查包的编译状态:执行以下语句,若状态为
INVALID,先解决编译错误
SELECT object_name, status FROM user_objects WHERE object_type IN ('PACKAGE', 'PACKAGE BODY') AND object_name = 'DATA_QUERY_PKG';
- 查看编译错误详情:
SHOW ERRORS PACKAGE data_query_pkg; SHOW ERRORS PACKAGE BODY data_query_pkg;
- 核对调用参数:
- 数清楚参数数量是否和存储过程定义一致
- 用命名参数(
p_new_date => ...)替代位置参数,避免顺序错误 - 确保参数类型匹配:DATE参数必须用
TO_DATE转换字符串,VARCHAR2参数长度不超限
内容的提问来源于stack exchange,提问作者ns102030
相关产品推荐
相关产品推荐

