0
我們正在嘗試實施一個修補客戶端軟件的程序 - 最初將運行一個.SQL,但如果腳本在任何時候都失敗,我們將回滾數據庫並停止客戶端DLL導入過程從工作。通過多個數據庫上的事務執行SQL腳本
我們的SQL腳本具有「GO」語句,因此我們無法將使用sp_executesql
的漂亮存儲過程放在一起,因爲這不允許「GO」 - 相反,如果我們有一個如下所示的SQL腳本:
USE [SomeDatabase]
BEGIN TRANSACTION
GO
IF (OBJECT_ID(N'[dbo].[ProcedureToUpdate]') IS NOT NULL)
DROP PROCEDURE [dbo].[ProcedureToUpdate]
GO
IF @@ERROR <> 0
AND @@TRANCOUNT > 0
ROLLBACK TRAN
GO
IF @@TRANCOUNT = 0
BEGIN
--Flag that the procedure hasn't been dropped, begin another transaction
BEGIN TRANSACTION
END
GO
PRINT 'Creating procedure'
GO
CREATE PROCEDURE [dbo].[ProcedureToUpdate]
AS
SELECT *
FROM [dbo].[SomeTable] st
INNER JOIN [dbo].[AnotherTable] at ON st.PK = at.fk
GO
IF @@ERROR <> 0
AND @@TRANCOUNT > 0
ROLLBACK TRAN
GO
IF @@TRANCOUNT = 0
BEGIN
--Flag that the procedure hasn't been created, begin another transaction
BEGIN TRANSACTION
END
GO
然後,我們正在執行在.NET中有問題的數據庫事務中的每個「動作」(由go語句拆分) - 如果循環內部出現任何故障,這將回滾數據庫。
Using con As New SqlConnection(ConnectionString)
con.Open()
Dim cmd As SqlCommand = con.CreateCommand()
Dim transaction As SqlTransaction = con.BeginTransaction("Upgrade")
cmd.Connection = con
cmd.Transaction = transaction
Try
For Each transactionalScript In transactionalScripts
cmd.CommandText = transactionalScript
Dim result = cmd.ExecuteNonQuery()
Next
transaction.Commit()
Catch ex As Exception
Log(String.Format("{0} : Script Failed", DateTime.Now.ToString()))
Log(String.Format("{0} : Reason: {1}", DateTime.Now.ToString(), ex.Message))
transaction.Rollback("Upgrade")
Log(String.Format("{0} : Database rolled back", DateTime.Now.ToString()))
End Try
End Using
最後 - 這是我的問題。我們需要處理多達4個.SQL腳本,每個腳本將用於單個服務器上的不同數據庫。如果4個腳本中的任何一個發生故障,我們應該回滾腳本受到影響的每個數據庫 - 有什麼建議嗎?