You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:51:44