私は2つのコマンドを持っていて、それらの両方が正しく実行される必要があります。だから私はトランザクションが必要だと思うが、それを正しく使う方法がわからない。
次のスクリプトの問題は何ですか?
BEGIN TRANSACTION [Tran1]
INSERT INTO [Test].[dbo].[T1]
([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)
UPDATE [Test].[dbo].[T1]
SET [Title] = N'az2' ,[AVG] = 1
WHERE [dbo].[T1].[Title] = N'az'
COMMIT TRANSACTION [Tran1]
GO
insert
コマンドは実行されましたが、update
コマンドには問題があります。実行中にエラーが発生した場合に、両方のコマンドをロールバックするためにこれを実装するにはどうすればよいですか。
トランザクションが成功した場合はtry/catchブロックを追加します。トランザクションが失敗した場合はトランザクションがロールバックされます。
BEGIN TRANSACTION [Tran1]
BEGIN TRY
INSERT INTO [Test].[dbo].[T1] ([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)
UPDATE [Test].[dbo].[T1]
SET [Title] = N'az2' ,[AVG] = 1
WHERE [dbo].[T1].[Title] = N'az'
COMMIT TRANSACTION [Tran1]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1]
END CATCH
ストアドプロシージャの最初に SET XACT_ABORT ON を設定して、エラーが発生した場合にトランザクションを自動的にロールバックするようにSql Serverに指示する必要があります。省略またはOFFに設定した場合は、各ステートメントの後に @@ ERROR をテストするか、 TRY ... CATCH rollback blockを使用する必要があります。
簡単な方法:
CREATE TABLE T
(
C [nvarchar](100) NOT NULL UNIQUE,
);
SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error.
SELECT * FROM T; -- Check before.
BEGIN TRAN
INSERT INTO T VALUES ('A');
INSERT INTO T VALUES ('B');
INSERT INTO T VALUES ('B');
INSERT INTO T VALUES ('C');
COMMIT TRAN
SELECT * FROM T; -- Check after.
DELETE T;