2009-12-09 177 views
2

我想從另一個SP調用SP。我知道我可以輕鬆地稱呼它。但問題是,如果在SP2中發生錯誤,那麼我想ROLLBACK SP1。從另一個存儲過程調用存儲過程

SP1
的begin tran
[一些代碼]
呼叫到SP2
[一些代碼]

SP2
BEGIN TRAN
[一些代碼]
[錯誤出現]
ROLLBACK TRAN

這將僅在sp2中回滾Tran。如果在sp2中發生錯誤,我也想回滾SP1。

任何幫助,將不勝感激。

+2

@vaibhav:我已經更新了標籤'sqlserver2005'到'sql-server-2005'。你會考慮使用現有的標籤嗎?謝謝。 – Sung 2009-12-09 22:36:38

+0

對於你想知道的關於錯誤處理的一切,但不敢問,Erland Sommarskog在這裏有一篇很好的(雖然未完成)的文章:http://sommarskog.se/error_handling_2005.html ...它也鏈接到他的兩個SQL Server 2000的文章,但其中一些概念仍然適用於更新的版本。 – 2009-12-10 04:16:40

回答

2

似人與其他信息網站問題...

它的要點是父過程將嘗試執行回滾的時候通過異常孩子已經擁有。解決這個問題的方法是讓父級在提交之前檢查@trancount。

http://forums.asp.net/t/1259708.aspx

Create procedure [dbo].[parent] as Begin Transaction Begin Try 
    Exec Child End Try Begin Catch 
    If @@Trancount > 0 
     RollBack End Catch Commit 


Create procedure [dbo].[Child] as Begin Transaction Begin Try 
    --Do inserts here End Try Begin Catch 
    If @@Trancount > 0 
     RollBack 
    RAISERROR('Error Occured',16,1) End Catch Commit 
+1

你不應該從這裏鏈接到這個網站。;-) – Tomalak 2009-12-09 21:56:15

+0

在您的鏈接中看不到任何內容。 – 2009-12-09 21:59:02

+0

謝謝,我可以使用@@錯誤來檢查「引發的錯誤」 – 2009-12-09 22:19:09

1

一種可能性是使用@ErrorCode INT OUTPUT參數創建SP2,該參數指示調用者是否需要回滾或提交。

+0

或使用返回值。 – erikkallen 2009-12-09 22:13:27

4

在SP2中嘗試RAISERROR

+0

您能否詳細說明一下。 – 2009-12-09 22:00:07

+0

在SP2內引發錯誤也會導致SP1回滾其事務。你做手動回捲還是自動回捲? – Tomalak 2009-12-09 22:03:37

+0

它的自動,使用「回滾Tran」 – 2009-12-09 22:06:28

0

在你的第二個SP中創建一個輸出參數,它是類型位,指示是否發生了錯誤。在此基礎上,你可以回滾SP 1

1

你可以使用這樣的錯誤代碼(我不是寫代碼只是我該怎麼做,如果我是你)

SP1 
DECLARE ReturnVal 
BEGIN TRAN 
CODE 
CALL SP1 ReturnVal output 
IF ReturnVal=errorvalue 
ROLLBACK TRAN 

SP2 
DECLARE ReturnVal output 
BEGIN TRAN 
CODE 
ERROR 
SET ReturnVal=errorVal 
ROLLBACK 
RETURN ReturnVal 
1

它不喜歡你的聲音需要嵌套事務。試着用try塊(僞碼)控制提交/回滾:

begin try 
    begin trans 
    do stuff 
    call other sp 
    do more stuff 
    commit trans 
end try 
begin catch 
    rollback trans 
    do something here to report failure to app 
end catch 

如果try塊內的任何地方發生錯誤,包括withing其他SP,控制將傳遞到catch塊和回滾事務。

+0

我認爲這值得考慮。但是不應該像其他人所說的那樣使用輸出參數。 – 2009-12-09 22:21:10

+0

@valbhav:考慮同時使用'RAISERROR'和'TRY ... CATCH' ... – Sung 2009-12-09 22:35:22

+0

我的方案會捕獲由您或服務器「引發」的錯誤。如果您需要報告第二個sp中的一些業務錯誤信息,則可以像其他人所建議的那樣調用raiserror,這是我的try-catch事件可以捕獲的。或者你可以使用輸出參數來報告錯誤。在這種情況下,try-catch不會對你有所幫助,你需要做一個'if'語句或者測試返回值。即使如此,trh try-catch仍然很好,可以捕捉到意想不到的錯誤。 – Ray 2009-12-09 22:58:47

相關問題