PL/SQL存储包PROCEDURE函数多结果返回适配需求及代码问题
问题分析与解决方案
问题根源
原代码里的GET_RESULTS过程使用SELECT ... INTO语句接收INFO_FUNCTION(Cd)的返回值,这种写法仅支持单行结果。当函数返回2条及以上数据时,会触发too_many_rows异常,但原代码的异常处理块只捕获了no_data_found,未处理该异常,导致过程静默失败,无任何返回。
修复方案
要处理函数返回的多行结果,需改用游标遍历每一行数据,对每条结果执行对应逻辑(比如你需要的多次SELECT调用)。以下是修正后的完整代码:
CREATE PACKAGE BODY TEST_PACKAGE IS PROCEDURE GET_RESULTS( p_Date IN DATE, p_Cd IN NUMBER ) IS -- 定义游标绑定函数返回的结果集 CURSOR c_info IS SELECT id, type, id1 FROM INFO_FUNCTION(p_Cd); v_id NUMBER; v_type VARCHAR2(100); -- 补充原代码缺失的数据类型 v_id1 NUMBER; -- 补充原代码缺失的数据类型 BEGIN -- 遍历游标中的每一行数据 FOR rec IN c_info LOOP v_id := rec.id; v_type := rec.type; v_id1 := rec.id1; -- 在这里添加针对单条结果的业务逻辑,比如调用SELECT -- 示例:根据当前行ID查询其他表数据 -- SELECT col1, col2 INTO v_col1, v_col2 FROM OTHER_TABLE WHERE id = v_id; -- 可添加调试输出(按需保留) DBMS_OUTPUT.PUT_LINE('处理结果:ID=' || v_id || ', Type=' || v_type || ', ID1=' || v_id1); END LOOP; EXCEPTION WHEN no_data_found THEN NULL; -- 无数据时的处理逻辑 WHEN OTHERS THEN -- 可选:捕获其他异常并处理,比如打印错误信息 DBMS_OUTPUT.PUT_LINE('错误:' || SQLERRM); END GET_RESULTS; -- 补充原代码缺失的过程结构(假设为主入口过程) PROCEDURE MAIN_PROCESS( p_Date IN DATE, p_Cd IN NUMBER ) IS lcur SYS_REFCURSOR; v_name TABLE1.NAME%TYPE; v_last_name TABLE1.LAST_NAME%TYPE; -- 修正原代码语法错误:LAST NAME → LAST_NAME v_result1 TABLE1.RESULT1%TYPE; v_result2 TABLE1.RESULT2%TYPE; v_c DATE; BEGIN OPEN lcur FOR SELECT NAME, LAST_NAME, RESULT1, RESULT2, GET_DATE_FUNCTION(p_Date, p_Cd) AS C FROM TABLE1; -- 按需遍历TABLE1的结果(原代码仅打开关闭游标,未处理数据) LOOP FETCH lcur INTO v_name, v_last_name, v_result1, v_result2, v_c; EXIT WHEN lcur%NOTFOUND; -- 处理TABLE1的单条数据逻辑 END LOOP; CLOSE lcur; GET_RESULTS(p_Date, p_Cd); -- 传入参数调用修复后的过程 END MAIN_PROCESS; END TEST_PACKAGE; /
关键修正说明
- 替换
SELECT ... INTO为游标循环,支持遍历函数返回的所有行 - 补充原代码缺失的变量数据类型,修正语法错误(字段名空格、SELECT字段缺逗号)
- 完善异常处理逻辑,避免静默失败
- 确保调用
GET_RESULTS时传入必要参数(原代码无参数调用会报错)
内容的提问来源于stack exchange,提问作者user19427142
相关产品推荐
相关产品推荐

