2011-10-07 43 views
1

我需要爲我的應用程序提供自動更新功能。 我在應用SQL更新時遇到問題。我在我的.sql文件中有更新的SQL語句,我想要實現的是如果一個語句失敗,那麼整個腳本文件必須回滾到 前。使用事務腳本文件自動更新

create procedure [dbo].[test1]   
@P1 varchar(200),   
@C1 int   
as   
begin 
Select 1 
end 

GO 

Insert into test (name) values ('vv') 

Go 

alter procedure [dbo].[test2]   
@P1 varchar(200),   
@C1 int   
as   
begin 
Select 1 
end 

GO 

現在在上面的例子,如果我得到的第三條語句錯誤「修改程序[DBO]。[TEST2]」那我要回滾前兩個變化,也即創建的「測試1 SP 「並將數據插入」測試「表

我應該如何處理此任務?任何幫助都感激不盡。

如果您需要任何更多的信息,然後讓我知道

回答

1

通常情況下,你會想在開始添加BEGIN TRAN,取出GO語句,然後處理ROLLBACK TRAN/COMMIT TRANTRY..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也會在最後刪除這些行。

+0

交易可以跨越批次。 –

+0

呵呵。不知道爲什麼我認爲他們不能。感謝您指出了這一點。我已經刪除了我的答案的一部分。我認爲其餘的依然是相關的。 –

+0

感謝您的建議。 我的數據庫是一種巨大的,所以我不會更喜歡備份/恢復。第二種方法對於我使每個執行的SQL的回滾語句更好。你能告訴我如何使用上面的例子來實現它。 非常感謝。 – user867198