这个问题以前曾被问过:

Finding COMMIT impossible in a Postgres Housekeeping Procedure

Postgresql invalid transaction termination when calling procedure

...但没有一个答案对我有用

我的存储过程中有一个循环.循环包含INSERTs,这需要是循环的written to the output table at the end of each pass.

  • 如果不使用COMMIT,则需要等到存储过程结束时才能访问结果.
  • 当我插入COMMIT(就在"end loop"之前)时,我收到以下错误消息:
ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function [...] at COMMIT 

SQL state: 2D000

我try 了官方文档中的第一个例子: https://www.postgresql.org/docs/12/plpgsql-transactions.html

我还是收到了同样的错误信息.

事实上,我举了一个更简单的例子:

CREATE TABLE test1 (a INTEGER);
CREATE PROCEDURE test_commit()
LANGUAGE plpgsql
AS $$
BEGIN
    FOR i IN 0..9 LOOP
        INSERT INTO test1 (a) VALUES (i);
            COMMIT;
    END LOOP;
END;
$$;

CALL test_commit();

相同的错误消息:

ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function test_commit() line 5 at COMMIT 

SQL state: 2D000

我正在运行pgAdmin 4的代码,我试着打开或关闭"自动提交".同样的结果.

我做错了什么?

推荐答案

调用事务处理过程的CALL不能以任何方式与其他语句一起包装在事务中.The doc you linked实际上提到了这一点,尽管没有任何细节或demonstration:

事务控制仅在来自顶层的CALLDO次调用或嵌套的CALLDO次调用中才可能进行,而没有任何其他干预命令.

类似于你需要单独运行VACUUM,因为它拒绝在事务中运行,你必须自己运行CALL:

  1. Select just the line with CALL test_commit(); and hit Execute/Refresh F5: pgAdmin execute selection
  2. Move the CALL test_commit(); to a separate Query Tool tab and execute it there. enter image description here
  3. As suggested by @Laurenz Albe, try switching from pgAdmin Query Tool to PSQL Tool and run it there instead. enter image description here

pgAdmin查询工具中的两个解决方案将工作,无论autocommit on/off状态.在psql中,你必须显式打开一个事务来关闭它.

Postgresql相关问答推荐

如何在PostgreSQL中对深度嵌套的jsonb属性创建索引

锁定模式与PostgreSQL中的另一种锁定模式冲突到底是什么意思?

是否可以在 postgres jsonb 列中的列表上创建索引

如何展平也在关系中使用的区分大小写的列

我可以使用 Rails 将数组存储在 hstore 中吗

当脚本工作时,Postgres now() 时间戳不会改变

在psql中,为什么有些命令没有效果?

错误:syntax error at or near "user"

如何在 PostgreSQL 触发器函数中获取表名?

Postgres 表中列的顺序会影响性能吗?

用于更改 postgresql 用户密码的 bash 脚本

在 PostgreSQL 中跳过每 n 个结果行

防止 CHARACTER VARYING 字段中出现空字符串

解释结果中的Recheck Cond是什么意思?

错误:表tablename上的更新或删除违反外键约束

全文的 Postgresql 前缀通配符

在 PostgreSQL 中 Select 进入临时表?

查询 JSON 列中的数组元素

Postgresql 对象 ID 和元组

如何在 PostgreSQL 中生成一系列重复数字?