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

如何编写Oracle批量迁移数据的存储过程(每批5万条)

Oracle大表批量数据迁移存储过程(每次5万条)

针对4亿条记录的大表迁移需求,以下是Oracle环境下的批量迁移存储过程实现,每次处理5万条数据,避免一次性操作占用过多系统资源:

基础版(复制数据,保留源表)

该版本仅将数据复制到目标表,源表数据保持完整:

CREATE OR REPLACE PROCEDURE BATCH_MIGRATE_DATA
IS
  v_batch_size CONSTANT NUMBER := 50000; -- 每次批量处理条数
  v_rows_processed NUMBER;
BEGIN
  v_rows_processed := v_batch_size; -- 初始化循环条件
  
  WHILE v_rows_processed = v_batch_size LOOP
    -- 批量插入数据到目标表
    INSERT INTO TABLE_2 (NAME, TAX_ID, PROD_CODE)
    SELECT NAME, TAX_ID, PROD_CODE
    FROM (
      -- 内层查询先获取数据,再通过ROWNUM限制条数
      SELECT t.*, ROWNUM rn
      FROM TABLE_1 t
      -- 在此添加数据筛选条件(如需要迁移部分数据)
      -- WHERE t.CREATE_DATE >= TO_DATE('20230101', 'YYYYMMDD')
    )
    WHERE rn <= v_batch_size;
    
    -- 获取本次实际处理的行数
    v_rows_processed := SQL%ROWCOUNT;
    
    -- 提交事务,释放UNDO空间并避免锁等待
    COMMIT;
    
    -- 可选:添加1秒延迟,降低系统瞬时负载(根据实际情况调整)
    DBMS_LOCK.SLEEP(1);
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE('迁移完成,累计处理记录数:' || (v_batch_size * FLOOR((v_rows_processed - 1)/v_batch_size) + v_rows_processed));
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    DBMS_OUTPUT.PUT_LINE('迁移失败:' || SQLERRM);
    RAISE; -- 抛出异常以便上层处理
END;
/

进阶版(带迁移标记,支持重复执行)

如果需要避免重复迁移、支持中断后继续执行,可以给源表添加IS_MIGRATED CHAR(1) DEFAULT 'N'字段,通过标记控制迁移范围:

CREATE OR REPLACE PROCEDURE BATCH_MIGRATE_DATA_WITH_MARK
IS
  v_batch_size CONSTANT NUMBER := 50000;
  v_rows_processed NUMBER;
BEGIN
  LOOP
    -- 锁定待迁移的记录,避免并发冲突
    UPDATE TABLE_1
    SET IS_MIGRATED = 'L' -- L=锁定状态
    WHERE ROWID IN (
      SELECT ROWID
      FROM TABLE_1
      WHERE IS_MIGRATED = 'N'
        -- 添加你的数据筛选条件
        -- AND t.TAX_ID IS NOT NULL
      AND ROWNUM <= v_batch_size
    );
    
    v_rows_processed := SQL%ROWCOUNT;
    
    -- 没有待迁移数据则退出循环
    IF v_rows_processed = 0 THEN
      COMMIT;
      EXIT;
    END IF;
    
    -- 将锁定的记录插入目标表
    INSERT INTO TABLE_2 (NAME, TAX_ID, PROD_CODE)
    SELECT NAME, TAX_ID, PROD_CODE
    FROM TABLE_1
    WHERE IS_MIGRATED = 'L';
    
    -- 将锁定标记更新为已迁移
    UPDATE TABLE_1
    SET IS_MIGRATED = 'Y' -- Y=已迁移状态
    WHERE IS_MIGRATED = 'L';
    
    COMMIT;
    DBMS_LOCK.SLEEP(1);
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE('迁移完成,累计处理记录数:' || v_rows_processed);
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    DBMS_OUTPUT.PUT_LINE('迁移失败:' || SQLERRM);
    RAISE;
END;
/

关键说明

  • 批量大小控制:v_batch_size设置为5万,可根据数据库IO、内存资源调整,IO性能优异的系统可适当调大。
  • 事务提交策略:每次批量操作后立即提交,避免大事务导致UNDO表空间耗尽、锁等待时间过长。
  • ROWNUM正确用法:必须在内层查询先获取全量符合条件的数据,再通过ROWNUM限制条数,否则会导致分页逻辑错误。
  • 与SQL Server方案差异:Oracle无TOP和OUTPUT语法,通过ROWNUM实现批量取数;本方案默认保留源表数据,若需删除源数据,可在插入后添加DELETE FROM TABLE_1 WHERE IS_MIGRATED = 'Y'语句。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:15:53