通常情況下,你會想在開始添加BEGIN TRAN
,取出GO
語句,然後處理ROLLBACK TRAN
/COMMIT TRAN
與TRY..CATCH
塊。
在處理DML時,雖然經常有語句必須在批處理的開始處,所以不能將它們包裝在TRY..CATCH
塊中。在這種情況下,你需要組裝一個知道如何回滾的系統。
一個簡單的系統就是在啓動時備份數據庫,如果有任何失敗(假設您是唯一一個訪問數據庫的人)。另一種方法是記錄每個成功運行的批處理,並具有相應的回滾腳本,以便在以後的批處理失敗時運行該腳本以將所有內容都回收。這顯然需要更多的工作(爲每個腳本PLUS編寫一個撤消腳本,充分測試回滾),並且如果在升級過程中人們仍然訪問數據庫,也可能會出現問題。
編輯: 這裏有一個簡單的TRY..CATCH
塊與交易處理的例子:
BEGIN TRY
BEGIN TRANSACTION
-- All of your code here, with `RAISERROR` used for any of your own error conditions
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
然而,TRY..CATCH
塊不能跨批次(也許這就是我說的交易couldn」我在想什麼的噸),所以在你的情況下,它可能會更類似於:
IF (OBJECT_ID('dbo.Error_Happened') IS NOT NULL)
DROP TABLE dbo.Error_Happened
GO
BEGIN TRANSACTION
<Some line of code>
IF (@@ERROR <> 0)
CREATE TABLE dbo.Error_Happened (my_id INT)
IF (OBJECT_ID('dbo.Error_Happened') IS NOT NULL)
BEGIN
<Another line of code>
IF (@@ERROR <> 0)
CREATE TABLE dbo.Error_Happened (my_id INT)
END
...
IF (OBJECT_ID('dbo.Error_Happened) IS NOT NULL)
BEGIN
ROLLBACK TRANSACTION
DROP TABLE dbo.Error_Happened
END
ELSE
COMMIT TRANSACTION
不幸的是,由於單獨的批次從t他GO
陳述你不能使用GOTO
,你不能使用TRY..CATCH
,你不能持續跨越批次的變量。這就是爲什麼我使用創建表來表示錯誤的非常簡單的技巧。
一個更好的方法是簡單地有一個錯誤表,並在其中尋找行。請記住,您的ROLLBACK
也會在最後刪除這些行。
交易可以跨越批次。 –
呵呵。不知道爲什麼我認爲他們不能。感謝您指出了這一點。我已經刪除了我的答案的一部分。我認爲其餘的依然是相關的。 –
感謝您的建議。 我的數據庫是一種巨大的,所以我不會更喜歡備份/恢復。第二種方法對於我使每個執行的SQL的回滾語句更好。你能告訴我如何使用上面的例子來實現它。 非常感謝。 – user867198