Проблема в том, что перед распространением исключения во внешний блок происходит неявный ROLLBACK, который удаляет точку сохранения, созданную блоком.
Вот пример, который воспроизводит проблему, но с использованием статического SQL:
begin
rollback; --clear all Transactions
savepoint SPX;
rollback;
raise no_data_found;
exception when no_data_found then
rollback to savepoint SPX;
end;
ORA-01086: savepoint 'SPX' never established in this session or is invalid ORA-06512: at line 7
К сожалению, вы застряли с таким поведением; динамический SQL должен быть запущен в своем собственном контексте, и если он вызывает исключение (и не обрабатывает его), выдается ROLLBACK.
Вам нужно будет создать точку сохранения перед запуском динамического SQL; В качестве альтернативы вы можете подавить ошибку ORA-01086:
begin
rollback; --clear all Transactions
execute immediate 'begin
savepoint SPX;
raise no_data_found;
end;';
exception when no_data_found then
begin
rollback to savepoint SPX;
exception when others then
if sqlcode != -1086 /*savepoint never established*/ then
raise;
end if;
end;
end;