2016-01-15 83 views
0

我想編寫一個從兩個表中刪除數據的存儲過程。 如果任一刪除操作失敗,我想確保沒有數據被刪除。如何創建和使用Oracle事務

這應該是一個簡單的任務,但我從未在Oracle工作過。 我不是如果我應該使用TRY/CATCH,TRANSACTIONS或SAVEPOINTS。

任何指導,將不勝感激。

目前我有:

CREATE OR REPLACE PROCEDURE SP_DELETE_STUFF 
(
    GROUPNAME IN VARCHAR2 
) AS 
BEGIN 

    SAVEPOINT Original_Start; 

    -- First delete all permissions for a given group 
    DELETE FROM my_table_1 
    WHERE group_name = GROUPNAME; 

    -- Second delete the group 
    DELETE FROM my_table_2 
    WHERE group_name = GROUPNAME; 

    EXCEPTION 
    WHEN OTHERS THEN 
    BEGIN 
     ROLLBACK TO SAVEPOINT Original_Start; 
     COMMIT; 
    END; 
    END 
+1

你有正確的想法,但是,我可能不會使用最後的COMMIT。你孤立你的邏輯(好),你已經把自己節省點(OK),並用它適當的(好)......然而,這樣做最終的提交,你會從別的地方提交的部分工作也就是說,無論你怎麼稱呼你的例程......注意,你甚至可能甚至不需要使用保存點(它們很方便,而且基本上已經正確使用它們),但是你可能不需要它們在這裏......也簡化了事情。 – Ditto

+0

添加到我的上述觀點,你可能會得到這樣正常不保存點執行以下操作:1)刪除初始'SAVEPOINT Original_Start;'2)去除'COMMIT;'3)改變'ROLLBACK TO SAVEPOINT Original_Start;'來只是'ROLLBACK;在'ROLLBACK後';'4)考慮增加'拋出'5)考慮增加'COMMIT;'2號刪除後,異常之前(但也許不是,如果這是從其他地方打來電話,要處理由調用者提交) – Ditto

回答

2

如果你的目標只是回滾所做的更改存儲過程的一個特定的呼叫做出如果有錯誤,你會使用一個savepointrollback to savepoint像你在這裏做。

我會質疑您在rollback to savepoint之後使用commit。這將提交存儲過程的調用者已經啓動的事務。當您的程序遇到錯誤時,您似乎不太可能要提交調用者的更改。所以我希望你想刪除commit

與事務範圍無關,我也希望您至少需要重新引發您捕獲的異常,以便調用者知道發生了故障。我希望你想要類似

EXCEPTION 
    WHEN OTHERS THEN 
    BEGIN 
     ROLLBACK TO SAVEPOINT Original_Start; 
     RAISE; 
    END; 
+0

也許增加一些關於命名'SAVEPOINT'的內容?你想確保你選擇一個不太可能被你稱之爲重複使用的名字。我想,「Original_Start」會有點過於常見,不安全。 –