0

我有存储过程,它包含对表的几个更新查询。它使用来自其他几个表的数据。因此,每个查询都在过程中提交,以释放查询中使用的表上的锁。在某些时候,我需要使用一些测试数据创建临时表。临时表名称与持久表的名称相同,以隐藏持久表。我想使用“on commit 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:好吧,看来我必须在会话中创建临时表并手动删除它们。必须使用表 oid 来确保临时表存在。像这样我认为:

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

1 回答 1

1

那么如何在事务块中使用过程调用呢?

正如CALL 的文档页面中所述,您不能:

如果 CALL 在事务块中执行,则被调用的过程不能执行事务控制语句。

问题中显示的语句序列无论如何都不起作用,因为该过程想要更新一个临时表,该表将被该更新上方的提交删除。

于 2019-01-08T14:57:33.900 回答