Postgresql
June 12, 2022

Update порциями по N строк в цикле PL/pgSQL.

Используются данные из демонстрационной базы https://postgrespro.ru/education/demodb, пример вымороченный, но ничего лучше в голову не пришло.

Создание таблицы для примера.

create table bookings.bookings_temp as
SELECT book_ref, book_date, total_amount, localtimestamp upd_date
FROM bookings.bookings;

В таблице всего 2 111 110 строк.

Далее (понятный без комментариев) код апдейта таблицы bookings_temp в цикле с фиксацией изменений по 50000 строк (переменная v_batch_qt). Кстати, для Oracle код будет на 99% таким же:

DO $
declare 
v_cnt int := 0;
v_rec record;
v_batch_qt int := 50000;
begin
  for v_rec in (select book_ref from  bookings.bookings_temp)
  loop
	update bookings.bookings_temp t1
	set book_date = t0.book_date + interval '9 minutes'
	,upd_date = localtimestamp
	FROM bookings.bookings t0
	where t0.book_ref = t1.book_ref and t0.book_ref = v_rec.book_ref;  
    v_cnt := v_cnt + 1;  
	if v_cnt >= v_batch_qt then 
	  v_cnt :=0;
	  --exit;
	  commit;
	end if; 
  end loop;
 commit;
 RAISE NOTICE 'финиш (%)',v_cnt;
end;
$;


Посмотрим, сколько всего порций закоммитилось.

select count (distinct upd_date) qt from bookings.bookings_temp

Вернулось 43 строки, т.е. были зафиксированы 42 изменения по 50 000 строк и одно на 1110.