Почему ошибкa: ORA-12838: невозможно прочитать/модифицировать объект после его модификации параллельным процессом
Изучаю PL/SQL. Выдали задание, в котором нужно найти ошибки в анонимном блоке:
DECLARE
l_Cnt_Del NUMBER;
BEGIN
INSERT --+ append
INTO NAME_TABLE
SELECT Cvm.*, Trunc(SYSDATE) Calc_Date
FROM NAME_TABLE1 Cvm;
DELETE FROM NAME_TABLE Cvh
WHERE Cvh.Calc_Date < Trunc(SYSDATE) - 14;
l_Cnt_Del := SQL%ROWCOUNT;
COMMIT;
END;
ORA-12838: невозможно прочитать/модифицировать объект после его модификации параллельным процессом
ORA-06512: на line 8
Почему возникает эта ошибка и как ее исправить?
Запрос с таблицами на фиддле.
Ответы (1 шт):
В коде вопроса логическая ошибка. Без подсказки оптимизатору + append, код рабочий.
С подсказкой + append будет выполнена прямая вставка (Direct Path) и с ней связаны некоторые ограничения, про которые в документации сказано следующее:
You can have multiple direct-path INSERT statements in a single transaction, with or without other DML statements. However, after one DML statement alters a particular table, partition, or index, no other DML statement in the transaction can access that table, partition, or index.
После прямой вставки в таблицу нельзя обращаться к этой таблице в этой же транзакции.
Другими словами, после прямой вставки надо завершить транзакцию до того, как выполнить следуюший DML с этой таблицей (в вопросе DELETE FROM NAME_TABLE в строке 8). Посмотрите на воспроизводимом примере, как надо правильно сделать:
create table tab1 (id, name) as
select rownum, 'name'||rownum from dual connect by level<100
/
create table tab2 (id, name, calc_date) as
select 1, 'name123', date'1970-01-01' from dual where 1=0
/
declare
CntDel number;
procedure copy is
pragma autonomous_transaction;
begin
insert /*+ append */ into tab2
select Cvm.*, Trunc (sysdate) calc_date from tab1 Cvm;
commit;
end;
begin
copy;
delete from tab2 Cvh
where Cvh.calc_date < Trunc (sysdate) - 14;
CntDel := sql%rowcount;
end;
/
PL/SQL procedure successfully completed.