2016-06-14 8 views
3

私は次のことを実行した場合:GOコマンドの奇妙な行動

CREATE TABLE t1 
    (a INT NOT NULL PRIMARY KEY); 
CREATE TABLE t2 
    (a INT NOT NULL REFERENCES t1(a)); 

INSERT INTO t1 VALUES (1); 
INSERT INTO t1 VALUES (3); 
INSERT INTO t1 VALUES (4); 
INSERT INTO t1 VALUES (6); 
GO 

をし、その後、私はこれを実行します。

SET XACT_ABORT ON; 

BEGIN TRANSACTION 
INSERT INTO t2 VALUES (1) 

INSERT INTO t2 VALUES (2) -- Foreign key error, entire transaction rolled back 

INSERT INTO t2 VALUES (3) 

COMMIT TRANSACTION 

を、その後何もokです。 t1に値2がなく、結果としてテーブルt2が空であるため、トランザクションはロールバックされます。

このトランザクションの途中でGOコマンドを追加すると、トランザクションはロールバックされず、番号3テーブルt2に挿入される。ここでは、コードは次のようになります。

SET XACT_ABORT ON; 

BEGIN TRANSACTION 
INSERT INTO t2 VALUES (1) 

INSERT INTO t2 VALUES (2) -- Foreign key error. 

GO --this command breaks the transaction 

INSERT INTO t2 VALUES (3) 

COMMIT TRANSACTION 

私はGOは、SQL文ではなく、実際にSQLサーバに送信されていないSQL Server Management Studioのユーティリティコマンドではないことを知っています。

ので、(GOコマンドを含むもの)の上に最後のコードスニペットを実行した後、私はSET XACT_ABORTONあるとき、私はSQL Server Management Studioの

+1

これは予想される動作とは完全に一致しています。 「GO」がどのように機能するのか、あなたの誤解かもしれません。 'batch'についてもっと理解するためにhttps://msdn.microsoft.com/en-us/library/ms188037.aspx?f=255&MSPPError=-2147217396を参照してください – techspider

+2

ポイント:' GO'は***をしません***ブレークトランザクション。トランザクションは、バッチレベルではなくセッションレベルの成果物です。 SSMSの 'GO'は、セッションではなくバッチを分割します。 – RBarryYoung

答えて

8

を使用

テーブルT2に番号3を見ることができる理由Transact-SQLステートメントで実行時エラー が発生すると、トランザクション全体が終了してロールバックされます。

最初のバッチで開封されたトランザクションは、が自動的にエラー時にロールバックされます。

次にSSMSは、最初のトランザクションが終了しました、これは新しい自動トランザクションをコミット始めると他のプロセスにバッチおよび

INSERT INTO t2 VALUES (3) 

COMMIT TRANSACTION 

オフ火災があり見ています。そして最後に予期せぬものがあります。COMMIT TRANSACTIONこれはエラーを発生させます。

第2バッチを変更して、最初のバッチのトランザクションが勝手にロールバックされたかどうかを確認することができます。

SET XACT_ABORT ON; 

BEGIN TRANSACTION 
INSERT INTO t2 VALUES (1) 

INSERT INTO t2 VALUES (2) -- Foreign key error. 

GO 

IF @@TRANCOUNT = 0 
    BEGIN 
    RAISERROR('Transaction closed',16,1); 
    RETURN; 
    END 

INSERT INTO t2 VALUES (3) 

COMMIT TRANSACTION 

それとも、SQLCMDモードをオンにして、エラーの後に処理すべき更なるバッチを希望しない場合は

:on error exit 

を使用することができます。

enter image description here

+0

私はこの答えにインラインでいますが、OPはロールバックする代わりにGOの後のテーブルで「2」を見ることができます。私はOPが質問について確信していたかどうか少し混乱していた:) – techspider

+4

いつものようにスポット。 – RBarryYoung

+0

はい、テーブルt2の番号2を見ることができます。これが問題です。コード/ペーストコードをコピーして試してみてください。 – Christian