UPSERT - Existe-t-il une meilleure alternative à MERGE ou @@ rowcount? [fermé]

14

Je me demandais si vous aviez rencontré une commande T-SQL similaire au concept d'UPSERT? L'exécution d'opérations INSERT | UPDATE à l'aide des options (1) ou (2) semble trop complexe et sujette aux erreurs.

OBJECTIF

Pour garantir que l'enregistrement souhaité (dans ce cas, employee_id 1) est à jour SANS avoir à écrire essentiellement la même requête deux fois.

LE CONTEXTE

  • nom de la table: employé
  • ID employé: possède une clé primaire et la propriété d'identité est définie sur true

OPTIONS

  1. exécuter une mise à jour SQL ... vérifier @@ rowcount = 0 et @@ error = 0 ... exécuter SQL INSERT si nécessaire

    • con: vous devez effectivement écrire deux fois la même requête, une fois en insert, une fois en mise à jour
    • con: plus de code = plus de temps à taper
    • con: plus de code = plus de place pour l'erreur

/programming/1106717/how-to-implement-a-conditional-upsert-stored-procedure "Mettre à jour en utilisant @@ rowcount"

  1. exécuter un SQL MERGE
    • con: vous devez effectivement écrire deux fois la même requête, une fois en insert, une fois en mise à jour
    • con: plus de code = plus de temps à taper
    • con: plus de code = plus de place pour l'erreur

http://technet.microsoft.com/en-us/library/bb510625.aspx "Fusion T-SQL"

  1. exécuter un SQL UPSERT (la fonctionnalité n'existe pas)
    • pro: vous définissez la relation données à table une fois (laissez SQL Server se soucier de savoir s'il s'agit d'un INSERT ou d'une UPDATE)
    • pro: moins de code = mise en œuvre plus rapide
    • pro: moins de code = plus faible probabilité

EXEMPLE UPSERT

UPSERT employeee (employee_id, employee_number, job_title, first_name, middle_name, Surname, modified_at) VALUES (1, '00 -124AB37 ',' Manager ',' John ',' T ',' Smith ', GetDate ());

  • si employee_id 1 n'existe pas: MS SQL exécute une instruction INSERT
  • si employee_id 1 existe: MS SQL s'exécute et l'instruction UPDATE
Pressacco
la source
4
Cela semble être une demande de fonctionnalité pour Microsoft, personne ici ne peut vous aider à résoudre. La solution proposée par Microsoft est MERGE. Si ce n'est pas assez flexible / puissant pour vous, alors vous avez besoin d'une solution différente qui n'existe pas encore.
Aaron Bertrand
3
À mon avis, MERGEest simple, flexible et fait également partie de SQL Standard. Le vrai problème avec les MERGEautres UPSERTimplémentations est l'escalade potentielle des verrous ou même les blocages qui n'ont rien à voir avec la syntaxe.
a1ex07
Si vous avez une question, n'hésitez pas à la poser. Tel qu'il est écrit, il s'agit essentiellement d'une diatribe sur l' MERGEimplémentation dans SQL Server.
JNK
Bonne question - existe-t-il essentiellement une instruction UPSERT où le serveur se demande s'il nécessite une insertion ou une mise à jour. Je suis d'accord, MERGE ne répond pas à ce que vous attendez logiquement d'une implémentation de "UPSERT". Étant donné que MS a choisi de mettre en œuvre de cette façon, ma question serait: qu'est-ce qui aurait pu être un défaut, ou impossible à mettre en œuvre, s'ils avaient tenté de mettre en œuvre la syntaxe que vous (et moi) souhaiterions?
youcantryreachingme

Réponses:

14

Je pense que la réponse simple à cette question est non. MERGEétait la réponse de Microsoft à la UPSERTlogique la plus compliquée . Et vous n'avez même pas énuméré la pire approche:

IF (SELECT COUNT ... ) > 0
    UPDATE
ELSE
    INSERT

Je viens de vomir dans ma bouche un peu en tapant ça, mais c'est en fait celui que je vois le plus souvent.

Dans tous les cas, s'il MERGEn'est pas flexible ou suffisamment puissant pour vous, je vous suggère de soumettre une demande de fonctionnalité à Microsoft à l' adresse http://connect.microsoft.com/sql/ et d'expliquer de manière approfondie votre analyse de rentabilisation. Tant que vous vous en tenez aux avantages réels de votre syntaxe proposée MERGE, vous avez mon vote. Si vous vous accrochez trop à la partie "sujette aux erreurs", je ne suis pas aussi susceptible d'accepter. Pourquoi? Parce que vous pouvez toucher n'importe quelle déclaration.

Cela dit, je ne pense pas que quiconque ici puisse faire spécifiquement pour vous. Vous devez étudier les problèmes potentiels avec MERGE:

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

Aaron Bertrand
la source
2
Merci Aaron. J'ai parcouru la documentation T-SQL sur MSDN et je n'ai pas trouvé ce que je cherchais; pensais juste que je le jetterais là au cas où je manquerais quelque chose. Bien que la déclaration MERGE ait du sens dans certaines situations, je ne peux m'empêcher de penser que c'est une solution de "marteau à marteau pour enfoncer un clou" pour une opération de sauvegarde simple. Je devrais peut-être prendre mon chapeau de programmeur et mettre mon DBA Fedora. Merci d'avoir pris le temps de partager vos réflexions.
Pressacco