2010-02-10 89 views
4

我想編寫一個SQL腳本來執行多個單獨的SQL語句;如果任何這些陳述失敗,我想回滾整個交易。所以,像這樣:如果有任何語句失敗,將回滾的SQL查詢

BEGIN TRANSACTION 

insert into TestTable values (1) 
insert into TestTable values (2) 
insert into TestTabe values (3) 

--if any of the statements fail 
ROLLBACK 
--else 
COMMIT 

這是用於MS SQL 2008.有什麼我可以做到這一點?也許某種異常處理?

我意識到在我的例子中,我可以檢查TestTable中的這些值,並確定這些語句是否以這種方式失敗。但實際上,我的SQL將更加複雜,我寧願將自己抽象爲知道SQL在做什麼。

回答

7

自2005年以來的SQL Server已經有例外的支持:

BEGIN TRY 
    BEGIN TRAN 

    INSERT INTO ... 

    COMMIT TRAN 
END TRY 
BEGIN CATCH 
    EXECUTE usp_LogAndRethrowError 
END CATCH 

你LogAndRethrowError則可以回滾任何註定的交易,一拉:

-- Make sure we are not in a live or 'doomed' transaction 
IF XACT_STATE() <> 0 
ROLLBACK TRANSACTION 
+1

回滾在哪裏? – Nathan 2010-02-10 17:29:08

+1

@Nathan聲明「您的LogAndRethrowError可以回滾任何註定事務」。所以你可以在Catch語句中添加ROLLBACK TRAN(或者讓SP爲你做)。 – Ben 2010-02-10 17:32:21

+0

沒有看到答案的某個部分。 – Nathan 2010-02-10 18:21:59

4

這是一個辦法,我已經在這樣做了過去:

Declare @HasError int; 
set @HasError = 0; 

BEGIN TRANSACTION 

insert into TestTable values (1) 
if (@@ERROR != 0) 
    set @HasError = 1 
insert into TestTable values (2) 
if (@@ERROR != 0) 
    set @HasError = 1 
insert into TestTabe values (3) 
if (@@ERROR != 0) 
    set @HasError = 1 

if @HasError > 0 
    ROLLBACK TRANSACTION 
ELSE 
    COMMIT TRANSACTION 
+0

另一個有趣的建議。謝謝。雖然我會使用與@error不同的名稱,所以它與@ERROR不同更清楚。 – manu08 2010-02-10 18:10:33

+0

那裏,這樣更好嗎? :) – Brettski 2010-02-10 18:15:44

+0

是的,我的頭痛現在少:) – manu08 2010-02-10 18:29:07

1

我很懶,並且已將此行添加到我的所有陳述中

SET XACT_ABORT ON 

http://technet.microsoft.com/en-us/library/ms188792.aspx

當SET XACT_ABORT爲ON時,如果 的Transact-SQL語句產生 運行時錯誤,整個事務 終止並回滾。

當SET XACT_ABORT爲OFF時,在某些情況下, 只引發錯誤的Transact-SQL語句 回滾 和交易繼續 處理。根據錯誤的嚴重程度 ,當SET XACT_ABORT爲OFF時,整個 事務可能會回退,即使在 也是如此。 OFF是默認設置 。

編譯錯誤,如語法錯誤, 不受SET XACT_ABORT的影響。

XACT_ABORT必須對大多數 OLE DB提供程序,包括SQL服務器 一個隱含 或顯式事務中設置用於數據 修改語句。唯一不需要此 選項的情況是 提供程序支持嵌套事務。 有關詳細信息,請參閱分佈式 查詢和分佈式事務。

SET XACT_ABORT的設置在執行或運行時設置爲 ,而不是在 解析時間。