BEGIN
FOR cur in (
with batch1 as
(select distinct trunc(date_column) start_date from db_a),
batch2 as (
select start_date,
trunc((row_number() over (order by start_date)-1) / 5) as batch_idx
from batch1)
select batch_idx, min(START_DATE) START_DATE, max(START_DATE)+1 END_DATE from batch2
group by batch_idx
order by 1)
LOOP
dbms_output.put_line('Processing dates from '||to_char(cur.START_DATE,'dd.mm.yyyy') || ' to ' || to_char(cur.END_DATE,'dd.mm.yyyy'));
insert into DB_TARGET(date_column,....)
select date_column,.... from DB_A
where date_column >= cur.START_DATE and date_column < cur.END_DATE;
commit;
END LOOP;
END;
/
循环将以预期的日期范围执行六次:
Processing dates from 01.05.2020 to 06.05.2020
Processing dates from 06.05.2020 to 11.05.2020
Processing dates from 11.05.2020 to 16.05.2020
Processing dates from 16.05.2020 to 21.05.2020
Processing dates from 21.05.2020 to 26.05.2020
Processing dates from 26.05.2020 to 31.05.2020
2条答案
按热度按时间jmo0nnb31#
如果您使用的是oracle 12c或更高版本,则可以按如下所示使用偏移量和获取来直接使用分页:
这里,x是迭代次数,从0开始。
假设一次需要5行。
对于第一次迭代:
对于第二次迭代:
一直到最后。。。。。
cu6pst1q2#
如果数据量太大,无法作为一个整体进行处理,请在分界日期上循环说明:
请注意,性能(即内存消耗)不仅与结果行的数量有关,还与处理数据的方式有关。
尽量避免在大容量数据上出现游标循环。首选的处理方式不是逐行,而是面向集合的,即。
如果源表
DB_A
在相关的日期列上分区(date_column
在上面的查询中)。查询将只选择那些日期受限的分区。您可以从并行dml中获益(同时使用sql方法)来提高性能。
例子
假设这张table
DB_A
列中包含30天的数据date_column
你想在5天内分批处理数据。您将以6个批次结束,如下面的查询所示。
查询首先从表中选择不同的截断天数,然后计算
batch_idx
使用ROW_NUMBER
除以5trunc
. 最后,边界日期为batch_idx
是经过计算的。您可以在游标循环中使用这个查询来处理数据,如下所示。
请注意
START_DATE
是包容的,但是END_DATE
是排他性的。循环将以预期的日期范围执行六次: