0

语义:

我使用 PostGreSql 9.0.3 作为我的 Dbms。实际上,我试图完成为我分配的目标之一,即当IF - Statement我的存储过程中的某些条件失败时,使用一些预定义的消息引发异常。由于该异常,应该需要回滚流程。

句法:

 For r3 in select itemname,stock from stock s,items it where s.itemno=it.itemno and it.itemno=$2[I].itemno and s.stockpointno=$1.stockpointno loop
    if xStock > r3.stock then
        RAISE EXCEPTION '%', r3.itemname || ' decreased down from the low stock level'; 
    end if;                           
 End Loop;

其中r3是记录,xStock是双精度变量。

然后在存储过程结束时,我只包含以下代码以回滚发生的事务。

Exception when raise_exception then rollback transaction;

我面临的问题是,一旦出现手动异常,就会出现以下错误。

DA00014:ERROR: XX000: SPI_execute_plan_with_paramlist failed executing query "rollback transaction": SPI_ERROR_TRANSACTION

尽管发生了上述错误,但在我签入表格时并未发生交易。我不知道在回滚过程中为什么会出现这个特定错误的确切原因。谁能告诉我在我的代码中可能犯的错误是什么?并提出解决此问题的解决方案。

4

1 回答 1

1

虽然一些数据库引擎允许COMMITROLLBACK在函数或过程中,但 PostgreSQL 不允许。任何这样做的尝试都会导致错误:

错误:不能在 PL/pgSQL 中开始/结束事务

这包括异常块内的代码。

另一方面,RAISE EXCEPTION单独的 a 将使用函数提供的错误消息中止事务,因此无需捕获您自己的异常。如果您刚刚删除了异常块,它将按预期工作。

正如Trapping Errors中的 plpgsql 文档所说:

默认情况下,PL/pgSQL 函数中发生的任何错误都会中止函数的执行,实际上也会中止周围事务的执行

您当前的代码引发异常,然后将其捕获并由于禁止ROLLBACK语句而在异常块本身中失败,这导致 SQL 引擎中止事务。

于 2013-10-22T11:20:16.670 回答