Как Марсело предлагает:
UPDATE mytable
SET new_column = <expr containing old_column>;
Если это занимает слишком много времени и завершается неудачно из-за ошибок «снимок слишком старый» (например, если выражение запрашивает другую высокоактивную таблицу), и если новое значение для столбца всегда равно NULL, вы можете обновить таблицу партии:
UPDATE mytable
SET new_column = <expr containing old_column>
WHERE new_column IS NULL
AND ROWNUM <= 100000;
Просто запустите это утверждение, COMMIT, а затем запустите его снова; промыть, повторять, пока не появится сообщение «0 строк обновлено». Это займет больше времени, но каждое обновление с меньшей вероятностью завершится ошибкой.
EDIT:
Лучшей альтернативой, которая должна быть более эффективной, является использование DBMS_PARALLEL_EXECUTE
API.
Пример кода (из документации Oracle):
DECLARE
l_sql_stmt VARCHAR2(1000);
l_try NUMBER;
l_status NUMBER;
BEGIN
-- Create the TASK
DBMS_PARALLEL_EXECUTE.CREATE_TASK ('mytask');
-- Chunk the table by ROWID
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID('mytask', 'HR', 'EMPLOYEES', true, 100);
-- Execute the DML in parallel
l_sql_stmt := 'update EMPLOYEES e
SET e.salary = e.salary + 10
WHERE rowid BETWEEN :start_id AND :end_id';
DBMS_PARALLEL_EXECUTE.RUN_TASK('mytask', l_sql_stmt, DBMS_SQL.NATIVE,
parallel_level => 10);
-- If there is an error, RESUME it for at most 2 times.
l_try := 0;
l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
WHILE(l_try < 2 and l_status != DBMS_PARALLEL_EXECUTE.FINISHED)
LOOP
l_try := l_try + 1;
DBMS_PARALLEL_EXECUTE.RESUME_TASK('mytask');
l_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
END LOOP;
-- Done with processing; drop the task
DBMS_PARALLEL_EXECUTE.DROP_TASK('mytask');
END;
/
Документы Oracle: https://docs.oracle.com/database/121/ARPLS/d_parallel_ex.htm#ARPLS67333