【问题标题】:call procedure from a function in postgresql从 postgresql 中的函数调用过程
【发布时间】:2021-11-09 09:06:34
【问题描述】:

我有一个包含提交的过程(postgresql v11),想从一个函数中调用他的过程。由于该过程已提交,因此出现以下错误,删除提交后它可以正常工作。是否有任何解决方法可以从函数调用带有事务控制语句的过程(我知道函数不支持事务,这就是它失败的原因,但想知道是否有任何替代方法?)

CREATE OR REPLACE FUNCTION public.f()
 RETURNS text
 LANGUAGE plpgsql
AS $function$ 
BEGIN
raise notice 'Starting Function!!!';
call public.p();
return 'success' ;  
END;
$function$;

CREATE OR REPLACE PROCEDURE public.p() LANGUAGE plpgsql AS $$
DECLARE src_schema TEXT;
BEGIN
raise notice 'Starting Procedure!!!';
commit;
RETURN;
END;
$$;

-- if the procedure has commit then its failing
imaods=> select public.f();
NOTICE:  Starting Function!!!
NOTICE:  Starting Procedure!!!
ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function p() line 5 at COMMIT
SQL statement "CALL public.p()"
PL/pgSQL function f() line 4 at CALL

-- if the commit is removed from the procedure then it works fine
imaods=> CREATE OR REPLACE PROCEDURE public.p() LANGUAGE plpgsql AS $$
imaods$> DECLARE src_schema TEXT;
imaods$> BEGIN
imaods$> raise notice 'Starting Procedure!!!';
imaods$> RETURN;
imaods$> END;
imaods$> $$;
CREATE PROCEDURE
imaods=>
imaods=> select public.f();
NOTICE:  Starting Function!!!
NOTICE:  Starting Procedure!!!
    f
---------
 success
(1 row)

【问题讨论】:

  • 您不能在函数中使用commit,也不能在从函数调用的过程中使用。正确的过程是提交调用函数,或者在调用过程之后调用者不是函数。不要试图解决正确的过程。您可能会成功,但您也可能会得到一些令人讨厌的副作用。

标签: postgresql


【解决方案1】:

The documentation 解释说:

事务控制只能在来自顶层的CALLDO 调用或嵌套CALLDO 调用中进行,而无需任何其他干预命令。比如调用栈是CALL proc1()CALL proc2()CALL proc3(),那么第二个和第三个过程可以执行事务控制动作。但是如果调用栈是CALL proc1()SELECT func2()CALL proc3(),那么最后一个过程不能做事务控制,因为中间有SELECT

原因是不能在 PostgreSQL 函数中进行事务管理。

【讨论】:

    猜你喜欢
    • 2018-03-14
    • 2020-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 2013-03-07
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多