Oracle: точки сохранения в пределах выполнения немедленно и ORA-01086 - PullRequest
0 голосов
/ 26 апреля 2018

Кто-нибудь знает, почему я получаю ORA-01086: точка сохранения 'SPX' никогда не была установлена ​​в этом сеансе или неверна в следующем коде?

begin 
    rollback; --clear all Transactions
    execute immediate 'begin
                           savepoint SPX;
                           raise no_data_found;  
                       end;';
exception when no_data_found then 
    rollback to savepoint SPX;
end;

Это работаетесли я не использую команду немедленного выполнения:

begin 
    rollback; --clear all Transactions
    begin
        savepoint SPX;
        raise no_data_found;  
    end;
exception when no_data_found then 
    rollback to savepoint SPX;
end;

Так это ожидаемое поведение или это что-то вроде ошибки?

Я использую Oracle Database 12c Enterprise EditionВыпуск 12.1.0.2.0 - 64-битное производство

Обновление: также работает следующий пример, в котором используется динамический SQL в сочетании с точками сохранения:

begin 
    rollback; --clear all Transactions
    execute immediate 'begin
                           savepoint SPX;
                       end;';
    rollback to savepoint SPX;
end;

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Проблема в том, что перед распространением исключения во внешний блок происходит неявный 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;
0 голосов
/ 26 апреля 2018

В Oracle Doc для оператора SAVEPOINT ist говорит:

Оператор SQL SAVEPOINT может быть встроен как статический SQL в PL / SQL.

Так что я думаю, это можно рассматривать как ожидаемое поведение.

...