11

挿入/更新の失敗をテストし、ある場合はこのトランザクションをロールバックする適切な方法は何ですか? 私の挿入/更新は3つの別々のステートメントであり、 @@ROWCOUNT は最後に実行されたステートメントのみを反映するため、私が持っているものは機能しないと思います。

BEGIN TRANSACTION Script;
GO

INSERT INTO TableA (id) VALUES (1)
INSERT INTO TableB (id) VALUES (1)
UPDATE TableC SET id=1 WHERE id=2
GO

IF (@@ROWCOUNT=3 AND @@ERROR=0)
    BEGIN
    COMMIT
    END
ELSE
    BEGIN
    PRINT 'Error: Rolling back transaction'
    ROLLBACK TRANSACTION Script
    END
GO
4

3 に答える 3

43

トランザクションを開始する前に SET XACT_ABORT ON を設定すると、エラーが発生した場合に自動的にロールバックが発行されます

SET XACT_ABORT ON

begin transaction

INSERT INTO TableA (id) VALUES (1)
INSERT INTO TableB (id) VALUES (1)
UPDATE TableC SET id=1 WHERE id=2

commit transaction

自分でロールバックしたい場合は、try .. catch block を使用してください

begin transaction

begin try

  INSERT INTO TableA (id) VALUES (1)
  INSERT INTO TableB (id) VALUES (1)
  UPDATE TableC SET id=1 WHERE id=2

  commit transaction

end try

begin catch
  raiserror('Message here', 16, 1)
  rollback transaction
end catch
于 2012-04-24T17:23:10.543 に答える
5

お使いのバージョンはわかりませんが、SQL 2005 以降、try/catch が使用されています。

begin transaction
begin try
   INSERT INTO TableA (id) VALUES (1)
   INSERT INTO TableB (id) VALUES (1)
   UPDATE TableC SET id=1 WHERE id=2
end try
begin catch
   SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage;
   while(@@trancount > 0)
   begin
      rollback transaction
   end
end catch
if (@@trancount <> 0)
begin
   commit transaction;
end
于 2012-04-24T17:34:14.517 に答える
0

失敗した挿入はスローします。「失敗した」更新は、@@ROWCOUNT を使用して検出できます。

于 2012-04-24T17:23:31.343 に答える