Oracle APEX 22.1存储过程apex_string.split循环更新表失效问题
问题说明
运行环境:Oracle APEX 22.1.0
需求场景:存储过程中使用apex_string.split拆分逗号分隔格式的入参P_EMPIDS(格式形如data1,data2,data3,data4),遍历拆分后的每一个值,逐行更新NB_ASSET_CODE表的对应记录。
原有代码问题:
- 无合法的迭代逻辑,LOOP块内直接执行
SELECT INTO语句,当拆分结果返回多行时会触发ORA-01422: 实际返回行数超出请求行数错误 - 无循环终止条件,会触发死循环
- 未做空值过滤,参数首尾带逗号、存在连续逗号时会拆分出空值,导致无效更新
正确实现写法
逐行循环写法(适配需要在循环内增加额外处理逻辑的场景)
使用FOR IN循环直接遍历拆分结果集,PL/SQL会自动完成游标打开、数据拉取、游标关闭的全流程,无需手动编写退出判断:
-- 变量声明段补充(如果存储过程已提前声明可忽略) -- L_EMPIDS 字段长度请和NB_ASSET_CODE表ASSET_CODE字段实际长度保持一致 DECLARE L_EMPIDS VARCHAR2(100); BEGIN FOR split_rec IN ( SELECT column_value AS emp_id FROM TABLE(apex_string.split(P_EMPIDS, ',')) WHERE column_value IS NOT NULL -- 过滤拆分产生的空值 ) LOOP L_EMPIDS := split_rec.emp_id; UPDATE NB_ASSET_CODE SET OWNER_ID = P_ASSET_2 WHERE COMPANY_ID = L_COMPANY_ID AND ASSET_CODE = L_EMPIDS; END LOOP; -- 按业务需求选择是否在此处提交事务 COMMIT; END;
批量更新写法(无逐行额外逻辑时优先使用,性能更高)
不需要写循环,直接通过关联查询一次性完成所有匹配记录的更新,避免逐行DML的性能开销:
MERGE INTO NB_ASSET_CODE t USING ( SELECT column_value AS emp_id FROM TABLE(apex_string.split(P_EMPIDS, ',')) WHERE column_value IS NOT NULL ) s ON ( t.COMPANY_ID = L_COMPANY_ID AND t.ASSET_CODE = s.emp_id ) WHEN MATCHED THEN UPDATE SET t.OWNER_ID = P_ASSET_2; COMMIT;
注意事项
- 如果入参
P_EMPIDS本身带括号(形如(data1,data2,data3)),拆分前需要先替换掉括号,否则首尾的ID会携带括号导致匹配失败,写法为apex_string.split(REPLACE(REPLACE(P_EMPIDS, '(', ''), ')', ''), ',') - 如果
ASSET_CODE字段为数值类型,拆分后需要对column_value做TO_NUMBER转换,避免隐式类型转换导致索引失效 - 批量更新前建议先把拆分后的结果打印日志,确认拆分结果符合预期后再执行更新操作
内容的提问来源于stack exchange,提问作者Kamiya
相关产品推荐
相关产品推荐

