2013-10-12 32 views
0

語義:軋製回,但錯誤依然存在

我使用PostgreSQL 9.0.3作爲我的數據庫管理系統。實際上,我嘗試完成爲我指定的目標之一,即在存儲過程中的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 

雖然發生了上述錯誤,但是在檢查表格時,並沒有發生事務。我不知道在回退過程中出現此特定錯誤的確切原因。有人可以告訴我在我的代碼中可能犯的錯誤嗎?並建議解決方案來解決這個問題。

+2

如果發生錯誤,則不需要顯式回滾事務。事務內部任何拋出的異常都會導致回滾。 –

+0

同樣的事情可以通過檢查條件和/或觸發器功能來完成。沒有循環,沒有遊標。 – wildplasser

+0

@IgorRomanchenko哦..那麼,在什麼情況下我們必須手動使用回滾?直到現在我錯誤地認爲回滾是由我們手動調用的。 –

回答

1

儘管某些數據庫引擎允許在函數或過程中使用COMMITROLLBACK,但PostgreSQL不允許。任何嘗試這樣做都會導致錯誤:

ERROR: cannot begin/end transactions in PL/pgSQL

這包括異常塊內的代碼。

另一方面,單獨一個RAISE EXCEPTION將中止事務與函數提供的錯誤消息,因此沒有必要陷入自己的異常。如果你只是刪除你的異常塊,它會按預期工作。

正如Trapping Errors表示,受PLPGSQL文檔:

By default, any error occurring in a PL/pgSQL function aborts execution of the function, and indeed of the surrounding transaction as well

您當前的代碼引發異常,然後捕獲它,並在異常塊失敗,因爲禁止ROLLBACK聲明,這導致SQL引擎本身中止交易。

相關問題