OracleDB:从表中批量复制数据(多次提交)

djp7away  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(200)

我有一个表TABLE_ORIG,并希望将数据复制到现有的空TABLE_COPY中。通常我可以:

INSERT INTO TABLE_COPY SELECT * FROM TABLE_ORIG ROWNUM <= 100000;
COMMIT;

但是我想把整个复制过程分成几批,并提交几次,中间可能会有sleep。下面是我尝试实现的伪代码(复制100,000行,但将它们分布在100次提交中=每次提交复制1000行):

i=0;
for (i < 100):
    INSERT INTO TABLE_COPY SELECT * FROM TABLE_ORIG WHERE ROWNUM <= 1000;
    COMMIT;
    i++;
    SLEEP 5 seconds;

如何在Oracle DB中执行此操作?

p5fdfcr1

p5fdfcr11#

开始,重要的是要了解您想要进行这种奇怪的数据复制的原因。通过使用游标进行中间事务来复制大量数据是错误的。还值得考虑其他会话在复制过程中可能对源表和目标表进行的更改。
如果我们在多个事务中复制数据,那么避免在每个后续请求中再次复制已经复制的数据是很重要的。这可以通过不同的方式实现:
1.基于代理键值将源数据划分为多个范围
1.按ROWID值将初始数据划分为多个范围
1.检查目标表中要复制的每个源行的副本。
我的示例使用后一种方法。优化不需要索引。

create table TABLE_ORIG as 
  select object_id, owner, object_name, object_type 
    from all_objects
/
Create table TABLE_COPY as select * from TABLE_ORIG where 1=0
/
declare
  p_chunk_size pls_integer := 10000;
  p_sleep_delay number := 1;
begin
  loop
    insert into TABLE_COPY 
      select * from TABLE_ORIG o 
        where not exists (
          select null from TABLE_COPY c2
            where c2.object_id = o.object_id
        )
        and rownum<=p_chunk_size;
     if sql%rowcount = 0 then
       exit;
     end if;
     dbms_output.put_line(sql%rowcount);
     commit;
     dbms_session.sleep(p_sleep_delay);
  end loop;
  commit; -- close last empty transaction
end;
/

dbfiddle

相关问题