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

Oracle嵌套循环运行异常(超出最大范围)问题排查

PL/SQL数据插入逻辑修复

非空due_date原有逻辑故障点

  • 计数器x定义在循环外层,处理完第一条记录后不会重置,后续记录的偏移量计算完全错误
  • INSERT语句的SELECT子句未限制当前行,每次循环会插入所有due_date非空的记录,产生大量冗余错误数据
  • 起始日期计算不符合规则:原逻辑未严格取sysdate的年月+opening_date的日作为起始值
  • 截止判断使用<会漏掉刚好等于due_date的月份,不符合「持续到due_date为止」的要求

修正后的非空due_date处理代码

DECLARE
    v_start_date DATE;
    v_curr_date DATE;
BEGIN    
    FOR rec IN (SELECT * FROM z_exp14_main WHERE due_date IS NOT NULL) LOOP    
        -- 按规则生成起始日期:取系统时间的年、月,拼接开户日期的日
        v_start_date := TO_DATE(TO_CHAR(SYSDATE, 'YYYYMM') || TO_CHAR(rec.opening_date, 'DD'), 'YYYYMMDD');
        -- 兼容开户日大于当月最大天数的场景,取当月最后一天
        v_start_date := LEAST(v_start_date, LAST_DAY(SYSDATE));
        v_curr_date := v_start_date;
        
        WHILE v_curr_date <= rec.due_date LOOP
            -- 直接插入当前循环行数据,避免全表查询
            INSERT INTO z_exp14_resualt 
            VALUES (rec.dep_id, v_curr_date, rec.rate * rec.balance);
            v_curr_date := ADD_MONTHS(v_curr_date, 1);
        END LOOP;
    END LOOP;
    -- 统一提交事务,可根据数据量调整提交频率
    COMMIT;
END;
/

原有正常逻辑(due_date为空)参考

declare
  i number := 1;
BEGIN
for i in 1..12 loop
  insert into z_exp14_resualt 
  select dep_id,ADD_MONTHS(ADD_MONTHS(opening_date,trunc( months_between (sysdate,opening_date))),i),rate*balance 
  from z_exp14_main
  WHERE due_date IS  null;
end loop;
COMMIT;
END;
/

z_exp14_main样例表参考

DEP_IDDUE_DATEBALANCERATEOPENING_DATE
20056634null2834281015-SEP-16
20056637null1802221007-NOV-14
20056639null587411028-AUG-14
4000002027-NOV-2150000002231-MAR-14
4000002323-APR-21630000002225-AUG-18

内容的提问来源于stack exchange,提问作者Zakaro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:06:04