web-dev-qa-db-fra.com

Manière correcte of a transaction autour de plusieurs insertions ou mises à jour

Quelle est la manière appropriée de tester les échecs d'insertion/mise à jour et d'annuler cette transaction s'il en existe? Je ne pense pas que ce que j'ai va fonctionner car mes insertions/mises à jour sont 3 déclarations distinctes et le @@ ROWCOUNT ne reflètera que la dernière instruction exécutée.

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
10
Joe Phillips

Si vous mettez SET XACT_ABORT ON avant de démarrer la transaction, en cas d'erreur, la restauration est automatiquement effectuée .

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

Si vous voulez effectuer une restauration vous-même, utilisez 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
37

Je ne sais pas quelle version vous utilisez, mais il y a eu try/catch depuis SQL 2005:

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
4
Ben Thul

Les inserts qui échouent vont lancer. Les mises à jour "en échec" peuvent être détectées à l'aide de @@ ROWCOUNT.

0
usr