web-dev-qa-db-fra.com

UPDATE s'il existe d'autre INSERT dans SQL Server 2008

Je veux savoir comment utiliser UPSERT ou en d'autres termes UPDATE if records exists Else enter new record opération dans SQL Server à l'aide d'une seule instruction?

Cet exemple montre comment y parvenir dans Oracle Here Mais il utilise la table Dual qui n’existe pas dans SQL Server.

Donc, toutes les alternatives SQL Server (pas de procédures stockées) s'il vous plaît?

39
Maven

Beaucoup de gens vous suggéreront d'utiliser MERGE, mais je vous le déconseille. Par défaut, cela ne vous protège pas plus que de multiples déclarations de la concurrence et de la concurrence, mais cela présente d'autres dangers:

http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

Même avec cette syntaxe "plus simple" disponible, je préfère quand même cette approche (la gestion des erreurs est omise pour des raisons 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;

Beaucoup de gens suggéreront de cette façon:

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 ce que cela fait, c’est que vous devrez peut-être lire le tableau deux fois pour localiser la ou les lignes à mettre à jour. Dans le premier exemple, il vous suffira de localiser une ou plusieurs lignes. (Dans les deux cas, si aucune ligne n'est trouvée lors de la lecture initiale, une insertion est effectuée.)

D'autres suggéreront de cette façon:

BEGIN TRY
  INSERT ...
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 2627
    UPDATE ...
END CATCH

Toutefois, cela pose problème si, pour la seule raison qui précède, laisser les exceptions de capture SQL Server que vous auriez pu éviter en premier lieu est beaucoup plus coûteux, sauf dans le cas rare où presque chaque insertion échoue. Je prouve autant ici:

Vous ne savez pas ce que vous pensez gagner à avoir une seule déclaration; Je pense que tu ne gagnes rien. MERGE est une déclaration unique, mais il doit quand même effectuer plusieurs opérations de toute façon, même si cela vous fait penser que ce n'est pas le cas.

91
Aaron Bertrand