【问题标题】:Commit, savepoint, rollback to in PostgreSQL?在 PostgreSQL 中提交、保存点、回滚?
【发布时间】:2011-07-23 20:50:26
【问题描述】:

有人能解释一下为什么这个函数中的 COMMIT 会返回 EXCEPTION 吗?

DECLARE
  XNar CURSOR (forDATE Varchar) IS 
   SELECT NARUCENO, ISPORUKA_ID FROM XDATA_NARUDZBE 
   WHERE TO_CHAR(XDATA_NARUDZBE.DATUM, 'DD.MM.YYYY') = forDATE;
 LastDate  DATE;
 OutResult INTEGER;
 curNAR    NUMERIC;
 curISP    VARCHAR;
 RXNar     RECORD; 
BEGIN

 OutResult := 1;

 SELECT MAX(DATUM) INTO LastDate FROM XDATA_NARUDZBE;  

 FOR RXNar IN XNar(TO_CHAR(LastDate, 'DD.MM.YYYY')) LOOP

   IF (RXNar.NARUCENO <> 0) AND (RXNar.ISPORUKA_ID = 'R01') THEN
     UPDATE NARUDZBE SET ISPORUCENO = RXNar.NARUCENO 
      WHERE NARUDZBE.PP_ID  = RXNar.PP_ID
        AND NARUDZBE.ART_ID = RXNar.ART_ID
        AND NARUDZBE.ISPORUKA_ID = 'R01';
   END IF;

  END LOOP;

 COMMIT; <--- ????

 RETURN OutResult;

 EXCEPTION
  WHEN OTHERS THEN
   OUTRESULT := 0;
   RAISE;    
   RETURN OutResult;

END;    

当函数中存在异常块时,为什么我不能使用 ROLLBACK TO SavePoint?

【问题讨论】:

    标签: postgresql plpgsql


    【解决方案1】:

    您不能在存储过程中使用 COMMIT,整个过程是它自己的事务。

    【讨论】:

    • 链接:this page的最后一段
    • @JackPDouglas:这就是 OP 需要的嵌套块。
    • 也就是说他需要在程序外commit?我的理解是他可以回滚过程中的子事务,但根本不能回滚commit(或显式rollback整个事务)
    • 我是 PG 的新手...谢谢您为我澄清!下一个问题呢?
    【解决方案2】:

    正如弗兰克海肯斯回答的那样,您不能使用 plpgsql 提交 plpgsql 存储函数/过程。但是,您可以使用 dblink(http://www.postgresql.org/docs/9.0/interactive/contrib-dblink-connect.html) 或其他存储过程语言(例如 plperl(untrusted))来解决此问题。看看这个讨论的链接。

    http://postgresql.1045698.n5.nabble.com/Re-GENERAL-Transactions-within-a-function-body-td1992810.html

    最重要的是,您使用其中一种方法打开一个新连接并在该连接上发出单独的事务。在大多数情况下工作并不理想,因为您要打开一个新连接,但在大多数用例中可能工作正常。

    【讨论】:

      【解决方案3】:

      PostgreSQL11 开头有一个procedure 模块。 基于手册的演示。

      CREATE OR REPLACE PROCEDURE insert_data_drop(_a integer, _b integer)
      LANGUAGE plpgsql
      AS $$
      begin
         INSERT INTO tbl(a) VALUES (_a);
         INSERT INTO tbl(b) VALUES (_b);
         Rollback;
         INSERT INTO tbl(a) VALUES (_a);
      end
      $$;
      

      现在CALL insert_data_drop(1, 2); 将在a 列中插入12 将不会被保存。 但是,SAVEPOINT 似乎不起作用。它会显示如下错误:

      ERROR:  unsupported transaction command in PL/pgSQL
      CONTEXT:  PL/pgSQL function insert_data_drop(integer,integer) line 5 at SQL stateme
      

      【讨论】:

        猜你喜欢
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        • 2012-12-05
        • 1970-01-01
        • 2013-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多