【问题标题】:Procedure call inside transaction事务内部的过程调用
【发布时间】:2019-05-25 18:37:54
【问题描述】:

我有一个存储过程,它包含对表的几个更新查询。它使用来自其他几个表的数据。因此,每个查询都在过程中提交,以释放查询中使用的表上的锁。 在某些时候,我需要使用一些测试数据创建临时表。临时表名称与持久表的名称相同,以隐藏持久表。我想使用“on commit drop”,但是,如果我开始事务临时表创建顺利,但在调用 my_very_big_procedure() 时,我收到一个错误“wrong end of transaction”并指向第一次提交内部过程。

为了保持代码简短,我将使用一些虚拟示例:

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

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

更新: 好吧,似乎我必须在会话中创建临时表并手动删除它们。必须使用表 oid 来确保临时表存在。 我认为是这样的:

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

【问题讨论】:

    标签: transactions procedure postgresql-11


    【解决方案1】:

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

    你不能,正如doc page for CALL中提到的那样:

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

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

    【讨论】:

    • Daaamn,好伤心:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多