2015-11-05 47 views
2

按照史蒂芬斯坦書

當一個異常在PL/SQL塊時,Oracle數據庫不回滾 任何在該塊DML語句所做的更改。你是應用程序邏輯事務的管理者,所以你決定應該發生什麼樣的行爲。
我試試看:
DML和異常處理 - 甲骨文

CREATE TABLE DML_Exception (exception_name VARCHAR2(20)); 
INSERT INTO DML_exception VALUES('CASE_NOT_FOUND'); 
INSERT INTO DML_exception VALUES('TOO_MANY_ROWS'); 

我都行我的表

Select * from DML_Exception 

現在我從表中刪除行和提高在PL/SQL塊中的例外。

BEGIN 
    DELETE FROM dml_exception; 
    raise value_error; 
END; 

但我的表仍然包含兩個行。我錯過了什麼?

+1

未提交的事務? – Stawros

+0

你在用什麼客戶?也許它在異常之後回滾? –

+0

作爲@Stawros sadid,你忘了COMMIT – pablomatico

回答

3

您錯過了本書的其他部分。是的,如果在塊中發生異常,則Steven爲真–,之前的所有DML效果都保留在原位。然而,本書還應該提到任何頂級SQL或PL/SQL語句(即匿名塊)執行都會爲該語句打開一個遊標,並且如果在遊標執行期間有異常,所有的DML效果都會完成在遊標執行期間被回滾。也許是一個簡單的例子會給你線索......

在你原來的例子,你執行...

BEGIN 
    DELETE FROM dml_exception; 
    raise value_error; 
END; 

...作爲頂級聲明。是的,在該塊的盡頭,儘管仍在,您的delete效果仍然存在。然而,你的塊引發了一個傳播到頂層遊標的異常。因此,爲了遵守atomicity的原則,Oracle回滾了打開的遊標的所有掛起效果。

如果你打電話給你的PL/SQL塊從另一個頂級PL/SQL塊,它可以處理並不會重新提高在較低的水平,PL/SQL塊產生的異常,內...

BEGIN 
    BEGIN 
     DELETE FROM dml_exception; 
     raise value_error; 
    END; 
EXCEPTION 
    WHEN others THEN NULL; 
END; 

...,那麼您的delete效果應保持不變。 (並且因爲在該塊中沒有提交,所以最終正在進行交易。)

+0

謝謝你的幫助,我的概念現在已經明確:) – Wolfgang