1

現在展開中のシステムをアップグレードする単一の T-SQL スクリプトを作成しようとしています。スクリプトには、次の混合が含まれます。

  • 新しいテーブル
  • 既存のテーブルの新しい列
  • 新機能
  • 新しいストアド プロシージャ
  • ストアド プロシージャの変更
  • 新しいビュー

これはかなり大規模なアップグレードであるため、スクリプトの一部が失敗した場合は、スクリプトをロールバックさせたいと考えています。以下に、試行したコードの概要を示します。

DECLARE @upgrade NVARCHAR(32);
SELECT @upgrade = 'my upgrade';

BEGIN TRANSACTION @upgrade
BEGIN
    PRINT 'Starting';
    BEGIN TRY
        CREATE TABLE x ( --blah...
        );

        ALTER TABLE y --blah...
        );

        CREATE PROCEDURE z AS BEGIN ( --blah...
        END
        GO  --> this is causing trouble!

        CREATE FUNCTION a (  --blah...

    END TRY
    BEGIN CATCH    
        PRINT 'Error with transaction. Code: ' + @@ERROR + '; Message: ' + ERROR_MESSAGE();
        ROLLBACK TRANSACTION @upgrade;
        PRINT 'Rollback complete';
        RETURN;
    END TRY
END
PRINT 'Upgrade successful';
COMMIT TRANSACTION @upgrade;
GO

注 - 一部の構文が完全ではないことはわかっています - コードのキーを再設定する必要があります

ストアド プロシージャをトランザクション ブロックに入れることができないようです。これには理由がありますか?という言葉の使い方のせいGOでしょうか。その場合、どうすれば SP をトランザクション ブロックに入れることができますか? トランザクション ブロックに入れることができるものに関する制限は何ですか? または、私が達成しようとしていることのより良い代替手段は何ですか?

ありがとう

4

2 に答える 2

3

Thomas Haratykが彼の答えで言ったように、あなたの問題は「行く」でした。ただし、トランザクションには必要な数のバッチを含めることができます。これが気に入らないのはtry/catchです。簡単な概念実証は次のとおりです。

begin tran
go
select 1
go
select 2
go
rollback

begin try
    select 1
    go
    select 2
    go
end try
begin catch
    select 1
end catch
于 2013-02-22T20:33:27.413 に答える
2

GO を削除し、動的 ​​SQL を使用してプロシージャを作成しないと失敗します。

EXEC ('create procedure z 
  as
  begin
    print "hello world"
  end')

GO は SQL キーワードではなく、バッチ区切り文字です。したがって、トランザクションに含めることはできません。

詳細については、次のトピックを参照してください。

SQL エラー:「CREATE/ALTER PROCEDURE」はクエリ バッチの最初のステートメントでなければなりませんか?

トランザクション内で「GO」を使用する

http://msdn.microsoft.com/en-us/library/ms188037.aspx

于 2013-02-22T15:27:39.520 に答える