62 votes

syntaxe pour MERGE / upsert sur une seule ligne dans SQL Server

J'essaie de faire une seule ligne d'insertion / mise à jour sur une table, mais tous les exemples sont pour les ensembles.

Quelqu'un peut-il corriger ma syntaxe s'il vous plaît:

 MERGE member_topic ON mt_member = 0 AND mt_topic = 110
WHEN MATCHED THEN UPDATE SET mt_notes = 'test'
WHEN NOT MATCHED THEN INSERT (mt_member, mt_topic, mt_notes) VALUES (0, 110, 'test')
 

La résolution par marc_s est de convertir la ligne unique en sous-requête - ce qui me fait penser que la commande MERGE n’est pas vraiment destinée aux upserts à une seule ligne.

 MERGE member_topic
USING (SELECT 0 mt_member, 110 mt_topic) as source
ON member_topic.mt_member = source.mt_member AND member_topic.mt_topic = source.mt_topic
WHEN MATCHED THEN UPDATE SET mt_notes = 'test'
WHEN NOT MATCHED THEN INSERT (mt_member, mt_topic, mt_notes) VALUES (0, 110, 'test');
 

103voto

Ian Boyd Points 50743

J'ai finalement eu la syntaxe Upsert en utilisant MERGE dans SQL Server 2008. En utilisant ce que Jacob voulait faire (un Upsert):

 IF EXISTS(SELECT * FROM member_topic WHERE mt_member = 0 AND mt_topic = 110)
BEGIN
    --update existing row
    UPDATE member_topic SET mt_notes = 'test'
END
ELSE
BEGIN
    --insert new row
    INSERT INTO member_topic (mt_member, mt_topic, mt_notes)
    VALUES (0, 110, 'test')
END
 

La syntaxe équivalente MERGE est la suivante:

 MERGE 
   member_topic
USING ( 
    VALUES (0, 110, 'test')
) AS foo (mt_member, mt_topic, mt_notes) 
ON member_topic.mt_member = foo.mt_member 
   AND member_topic.mt_topic = foo.mt_topic
WHEN MATCHED THEN
   UPDATE SET mt_notes = foo.mt_notes
WHEN NOT MATCHED THEN
   INSERT (mt_member, mt_topic, mt_notes)
   VALUES (mt_member, mt_topic, mt_notes)
; --A MERGE statement must be terminated by a semi-colon (;).
 

46voto

marc_s Points 321990

Fondamentalement, vous êtes sur la bonne voie - mais il vous manque une source à partir de laquelle vous souhaitez fusionner les données essayer quelque chose comme cela:

MERGE 
   member_topic AS target
USING 
   someOtherTable AS source
ON 
   target.mt_member = source.mt_member 
   AND source.mt_member = 0 
   AND source.mt_topic = 110
WHEN MATCHED THEN 
   UPDATE SET mt_notes = 'test'
WHEN NOT MATCHED THEN 
   INSERT (mt_member, mt_topic, mt_notes) VALUES (0, 110, 'test')
; 

Il n'y a pas de syntaxe particulière pour une seule ligne de FUSION - tout ce que vous devez faire est d'utiliser un bon clause. Avec que de la bonne condition dans l' ON clause, vous pouvez limiter la source sur une seule ligne - pas de problème.

Et n'oubliez pas le point-virgule de fin! Pas de blague - c'est important!

Voir cet article de blog pour une très bonne intro MERGE.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X