Я пытаюсь использовать оператор insert into
, но получаю ошибку:
ORA-01628: достигнуто максимальное количество экстентов (32765) для сегмента отката _SYSSMU134_1882489978 $
Увеличение табличного пространства UNDO
не вариант, поэтому я хотел бы добавить способ вставки этих данных кусками (например, с 1 миллионом строк за раз). Может ли кто-нибудь помочь переписать эту процедуру таким образом?
CREATE OR REPLACE PROCEDURE create_chunks (
p_source_table IN VARCHAR2,
p_table_name_chunk IN VARCHAR2,
p_chunks IN VARCHAR2
) AS
v_insert_sql CLOB;
BEGIN
v_insert_sql := 'INSERT INTO ' || p_table_name_chunk ||
' (rid, chunk_number) ' ||
'SELECT /*+ parallel(64) */ rowid rid,' ||
'mod( ora_hash(rowid), :p_chunks ) as chunk_number '
'FROM ' || p_source_table;
EXECUTE IMMEDIATE v_insert_sql USING p_chunks;
COMMIT;
END;
Этот v_insert_sql
не работает с вышеупомянутой ошибкой. У меня есть рабочее решение с использованием курсора, подобного так:
DECLARE
CURSOR v_cur IS SELECT /*+ parallel(64) */
rowid rid, mod( ora_hash(rowid), 20000 ) AS chunk_number
-- I need this table to be parametric name
FROM some_table;
TYPE t_sample IS TABLE OF v_cur%ROWTYPE;
v_sample t_sample;
v_row_limit CONSTANT NUMBER := 1000000;
BEGIN
OPEN v_cur;
LOOP
FETCH v_cur BULK COLLECT INTO v_sample LIMIT v_row_limit;
FORALL i IN v_sample.first .. v_sample.last
INSERT INTO chunk_table VALUES v_sample(i);
COMMIT;
EXIT WHEN v_cur%NOTFOUND;
END LOOP;
CLOSE v_cur;
END;
Я не могу переместить этот курсор прямо в процедуру, так как имя таблицы меняется, и мне нужно, чтобы оно было параметрическим, так как при использовании курсора мне приходится повторять один и тот же код для разных таблиц. Так что вопрос в том, как с этим бороться?