根据文档(https://www.postgresql.org/docs/current/app-psql.html),即使将AUTOCOMMIT设置为off,PSQL也会在不在事务块中的任何命令之前发出隐式BEGIN,该命令本身不是BEGIN或其他事务控制命令,也不是不能在VACUUM等事务块中执行的命令。(不幸的是,CALL与VACCUM的处理方式不同)。根据Shaun Thomas (https://blog.2ndquadrant.com/pg-phriday-stored-procedures-postgres-11/)的说法,发生无效事务终止错误是因为不可能从过程中关闭当前事务(在本例中是由PSQL发起的事务)。我已经尝试了与事务控制相关的所有PSQL设置,但所有设置都出现了无效事务终止错误;即使PSQL处理的命令文件只包含CALL语句。
这是我调用的过程:
create or replace procedure producto$cargar_imagenes(_super$ bigint, _archivo$ character varying) as $$
declare
_msg character varying;
_log rastro_proceso%ROWTYPE;
begin
perform rastro_proceso_temporal$insert(_super$);
perform producto$cargar_imagenes$biz(_super$, _archivo$);
if (_super$ is not null and _super$ > 0) then
perform producto$cargar_imagenes$log(_super$, _archivo$);
else
perform tarea_usuario$private$update(6519204281880642486, null);
end if;
commit;
end;
$$ language plpgsql set search_path = public;它在commit语句中失败;如果我注释掉它,它就可以工作。
发布于 2018-11-09 06:46:43
删除SET子句。每个the documentation:
如果SET子句附加到过程,则该过程不能执行事务控制语句(例如,COMMIT和ROLLBACK,具体取决于语言)。
发布于 2020-01-09 01:11:58
在pg11 (在V11.6中测试)中,如果您在过程定义中包含“安全定义器”子句,您似乎也会遇到同样的问题。所以我猜安全定义器是一个"SET“子句。
当我删除安全定义器时,我可以在过程定义中包含一个COMMIT语句,而不会在COMMIT语句上得到错误:invalid transaction termination。
同样不幸的是,这是一个运行时错误,而不是编译错误。
https://stackoverflow.com/questions/53214740
复制相似问题