Вызов процедуры внутри транзакции - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть хранимая процедура, которая состоит из нескольких запросов на обновление таблицы.Он использует данные из нескольких других таблиц.Таким образом, каждый запрос фиксируется внутри процедуры, чтобы снять блокировки таблиц, используемых в запросе.В какой-то момент мне нужно создать временные таблицы с некоторыми тестовыми данными.Имена временных таблиц совпадают с именами постоянных таблиц для теневых постоянных таблиц.И я хочу использовать «on drop drop», но, если я начинаю, создание временной таблицы транзакций проходит гладко, но при вызове my_very_big_procedure () я получаю ошибку «неправильный конец транзакции» и указывает на первый коммит внутри процедуры.

Чтобы код был коротким, я использую несколько фиктивных примеров:

create or replace procedure my_very_big_procedure() as 
$$ 
begin
   insert into maintable select from table1, some_table, some_other_table;
   commit;

   update maintable using table1;
   commit;

   update maintable using table2;
   commit;
end;
$$ language pgplsql

begin
    create temp table maintable (like public.maintable) on commit drop;
    create temp table table1 (like public.table1) on commit drop -- works fine
    insert into table1 values %s  -- also works fine
    create temp table table2 (like public.table2) on commit drop -- again it's OK
    insert into table2 values %s -- and data's got inserted
    call my_very_big_procedure() -- and here comes an ERROR :(
    commit
end

Так, как я могу использовать вызов процедуры внутри блока транзакции?

UPD: Ну, кажется, у меня естьсоздавать временные таблицы в сеансе и удалять их вручную.Нужно использовать table oid, чтобы гарантировать, что временная таблица существует.Вот так я думаю:

select case when 'public.teblename'::regclass::oid = 'tablename'::regclass::oid then 'temp table exitsts' else 'no temp table - no drop' end.

1 Ответ

0 голосов
/ 08 января 2019

Так, как я могу использовать вызов процедуры внутри блока транзакции?

Вы не можете, как упомянуто на странице документа для CALL :

Если CALL выполняется в блоке транзакции, то вызываемая процедура не может выполнять операторы управления транзакциями.

Последовательность операторовпоказанный в вопросе не будет работать в любом случае, потому что процедура хочет обновить временную таблицу, которая была бы отброшена коммитом чуть выше этого обновления.

...