代码之家  ›  专栏  ›  技术社区  ›  fmark

我能让PostgreSQL忽略事务中的错误吗?

  •  13
  • fmark  · 技术社区  · 14 年前

    我使用PostgreSQL和Postgis扩展进行即席空间分析。我通常在psql中手工构造和发出SQL查询。我总是在事务中包装一个分析会话,所以如果我发出一个破坏性的查询,我可以回滚它。

    但是,当我发出包含错误的查询时,它会取消事务。任何进一步的查询都会引发以下警告:

    错误:当前事务是 中止,命令被忽略,直到结束 事务块

    有什么方法可以让我停止这种行为吗?每次我输入错误时,回滚事务并重新运行以前的查询是令人厌烦的。

    5 回复  |  直到 7 年前
        1
  •  10
  •   leonbloy    14 年前

    (更新:不需要手工操作,我在PostgreSQL邮件列表中询问,结果发现这个行为已经通过 ON_ERROR_ROLLBACK 在psql客户机中设置)

    为了详细说明Simon的答案(+1),在您的场景中,您可以在每个交互式查询之后常规地添加一个保存点,始终使用相同的名称(如果查询成功,它会写入上一个)。如果出现错误,请返回上次保存的文件,然后从中继续。

    此工作模式的示例:

    db=# select * from test_gral ;
     i |  t   |  n
    ---+------+------
     1 | text | 10.0
    (1 row)
    
    db=# begin;
    BEGIN
    db=#  insert into test_gral values (2,'xx',20); savepoint sp;
    INSERT 0 1
    SAVEPOINT
    db=#  insert into test_gral values (3,'xx',30); savepoint sp;
    INSERT 0 1
    SAVEPOINT
    db=#  insert into test_gralxx values (4,'xx',40); savepoint sp;
    ERROR:  relation "test_gralxx" does not exist
    LINE 1: insert into test_gralxx values (4,'xx',40);
                        ^
    ERROR:  current transaction is aborted, commands ignored until end of transaction block
    db=# ROLLBACK TO SAVEPOINT sp;
    ROLLBACK
    db=#  insert into test_gral values (4,'xx',40); savepoint sp;
    INSERT 0 1
    SAVEPOINT
    db=# commit;
    COMMIT
    db=# select * from test_gral ;
     i |  t   |  n
    ---+------+------
     1 | text | 10.0
     2 | xx   |   20
     3 | xx   |   30
     4 | xx   |   40
    (4 rows)
    
        2
  •  4
  •   Szymon Lipiński    14 年前

    关闭它是不可能的,但是你可以使用不同的东西。有一些类似于savepoint的东西:

    http://www.postgresql.org/docs/8.4/interactive/sql-savepoint.html

    因此,您可以将事务回滚到某个较早的点,而不必将整个事务都转为黑色。

        3
  •  1
  •   Stephen Denne    14 年前

    可以编写一个接受字符串参数的函数, executes 它使用了 exception 为了不中止您的事务,子句必须为您希望执行的每个语句调用该函数,这是一个巨大的痛苦。

        4
  •  0
  •   Yann Ramin    14 年前

    不,没有办法关掉这个。一个错误隐式地为您中止事务,因此您必须回滚并重试。

        5
  •  0
  •   Dan    7 年前

    简单的答案是运行

    my_db=> \set ON_ERROR_ROLLBACK interactive
    

    在交互式会话中。也见 this blog post 通过它的实现者。