Beaucoup de gens vous suggéreront d'utiliser MERGE
, mais je vous mets en garde contre cela. Par défaut, cela ne vous protège pas plus de la concurrence et des conditions de concurrence que plusieurs déclarations, mais cela introduit d'autres dangers :
- Soyez prudent avec l'instruction MERGE de SQL Server
- Ce qu'il faut éviter si vous souhaitez utiliser MERGE
- Modèles et anti-modèles SQL Server UPSERT
Même avec cette syntaxe "plus simple" disponible, je préfère toujours cette approche (gestion des erreurs omise par souci de brièveté) :
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;
Plus d'infos sur cet UPSERT
approche ici :
- Veuillez cesser d'utiliser cet anti-modèle UPSERT
Beaucoup de gens suggéreront ceci :
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
UPDATE ...
END
ELSE
BEGIN
INSERT ...
END
COMMIT TRANSACTION;
Mais tout cela permet de s'assurer que vous devrez peut-être lire le tableau deux fois pour localiser la ou les lignes à mettre à jour. Dans le premier exemple, vous n'aurez besoin de localiser la ou les lignes qu'une seule fois. (Dans les deux cas, si aucune ligne n'est trouvée à partir de la lecture initiale, une insertion se produit.)
D'autres suggéreront ceci :
BEGIN TRY
INSERT ...
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 2627
UPDATE ...
END CATCH
Cependant, cela est problématique si, pour aucune autre raison que de laisser SQL Server intercepter des exceptions que vous auriez pu empêcher en premier lieu, cela coûte beaucoup plus cher, sauf dans le cas rare où presque toutes les insertions échouent. Je le prouve ici :
- Vérifier les éventuelles violations de contraintes avant d'entrer TRY/CATCH
- Impact sur les performances des différentes techniques de gestion des erreurs
Vous ne savez pas ce que vous pensez gagner en ayant une seule déclaration ; Je ne pense pas que tu gagnes quoi que ce soit. MERGE
est une instruction unique, mais elle doit quand même effectuer plusieurs opérations - même si cela vous fait penser que ce n'est pas le cas.