【问题标题】:ROLLBACK TO SAVEPOINT inside a STORED procedure in postgreSQL 11 and the below code is failing to compile?在 postgreSQL 11 的 STORED 过程中回滚到 SAVEPOINT 并且以下代码无法编译?
【发布时间】:2020-03-12 11:44:47
【问题描述】:

升级到 postgresSQL 11,以下存储过程无法编译。

create or replace PROCEDURE savePointProc(startOrRollbak INTEGER, inVar VARCHAR) 
as $$
DECLARE
BEGIN   
    IF startOrRollbak = 0 THEN
       SAVEPOINT inVar;
     ELSE
       ROLLBACK TO SAVEPOINT inVar ;
     END IF;
END;
$$ LANGUAGE plpgsql;

在 postgreSQL 11 中

错误:“TO”处或附近的语法错误 第 8 行:回滚到保存点 inVar ; ^ SQL 状态:42601 字符:180

有人能指出上面的错误导致程序编译失败吗?

已删除错误:“TO”处或附近的语法错误

create or replace PROCEDURE savePointProc(startOrRollbak INTEGER, inVar 
VARCHAR) as $$
DECLARE
BEGIN   
   IF startOrRollbak = 0 THEN
      SAVEPOINT inVar;
   ELSE
      ROLLBACK TO inVar ;
   END IF;
END;
$$ LANGUAGE plpgsql;

error :
LINE 8:      ROLLBACK TO inVar ;
                      ^
SQL state: 42601
Character: 180

【问题讨论】:

  • 检查这是否有帮助:es.stackoverflow.com/questions/125440/…
  • 谢谢,我相信这个错误更多地与 ROLLBACK TO* 相关
  • The SQL standard specifies that the key word SAVEPOINT is mandatory, but PostgreSQL and Oracle allow it to be omitted 参考:postgresql.org/docs/11/sql-rollback-to.html
  • 已尝试省略 SAVEPOINT 关键字,但在 TO ERROR 上出现相同的错误:“TO”第 8 行或附近的语法错误:ROLLBACK TO inVar ; ^ SQL 状态:42601 字符:180
  • 你能在格式化代码中发布你的错误吗?从'^'指向的问题中还不太清楚。

标签: postgresql


【解决方案1】:

看起来 Pl/pgSQL 语法接受 SAVEPOINT ... 但不接受 ROLLBACK TO ... 语法。

您可以尝试使用动态SQL:编译时没有错误但在执行时失败(使用PG 11.7测试):

drop table t;
DROP TABLE
create table t(x int);
CREATE TABLE
create or replace procedure tsp(inVar VARCHAR)
as $$
BEGIN   
      SAVEPOINT inVar;
      insert into t values(1);  
      EXECUTE "ROLLBACK TO $1" USING inVar;
END;
$$ 
LANGUAGE plpgsql;
CREATE PROCEDURE
There is no previous error.
call tsp('sp1');
psql:tsp.sql:13: ERROR:  unsupported transaction command in PL/pgSQL
CONTEXT:  PL/pgSQL function tsp(character varying) line 3 at SQL statement
psql:tsp.sql:14: ERROR:  0A000: unsupported transaction command in PL/pgSQL
CONTEXT:  PL/pgSQL function tsp(character varying) line 3 at SQL statement
LOCATION:  exec_stmt_execsql, pl_exec.c:4194
select * from t;
 x 
---
(0 rows)

看起来在 Pl/pgSQL 中使用 SAVEPOINT 的正确方法是带有 EXCEPTION 子句的 BEGIN/END 块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多