0

クライアントソフトウェアにパッチを適用するプログラムを実装しようとしています。最初は.SQLが実行されますが、スクリプトが失敗した場合は、データベースをロールバックして、クライアントDLLのインポートプロセスが機能しなくなります。

SQLスクリプトには「GO」ステートメントが含まれているため、「GO」が許可されていないため、使用するための気の利いたストアドプロシージャをまとめることができませんsp_executesqlでした。代わりに、次のような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スクリプトを処理する必要があります。これらのスクリプトは、それぞれ1つのサーバー上の異なるデータベース用です。4つのスクリプトのいずれかが失敗した場合、スクリプトが影響を与えたすべてのデータベースをロールバックする必要があります-何か提案はありますか?

4

1 に答える 1

0

の使用を見てくださいTransactionScope

内で複数の接続を使用する場合TransactionScopeは、分散トランザクションが参加します。これには独自の要件(DTCなど)がありますが、それは確かにあなたが探し始めたいところです。

于 2012-09-14T11:59:39.273 に答える