J'ai 2 commandes et j'ai besoin que les deux soient exécutées correctement ou aucune d'entre elles. Je pense donc avoir besoin d'une transaction, mais je ne sais pas comment l'utiliser correctement.
Quel est le problème avec le script suivant?
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
La commande INSERT
est exécutée, mais la commande UPDATE
a un problème.
Comment puis-je implémenter ceci pour annuler les deux commandes si l'une d'entre elles présente une erreur d'exécution?
Ajoutez un bloc try/catch. Si la transaction réussit, les modifications seront validées. Si la transaction échoue, la transaction est annulée:
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
Au début de la procédure stockée, il faut mettre SET XACT_ABORT ON pour indiquer à Sql Server d'annuler automatiquement la transaction en cas d'erreur. S'il est désactivé ou défini sur OFF, il est nécessaire de tester @@ ERROR après chaque instruction ou d'utiliser TRY ... CATCH rollback block.
Approche facile:
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;