2010-03-19 7 views
53

Ich versuche, eine einzelne Zeile einfügen/aktualisieren auf einer Tabelle, aber alle Beispiele gibt es für Sätze.Syntax für einzelne Zeile MERGE/upsert in SQL Server

Kann jemand reparieren meine Syntax bitte:

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') 

Auflösung pro marc_s ist die einzige Zeile in eine Unterabfrage zu konvertieren - die mir der MERGE Befehl denken macht, ist nicht wirklich für einreihige upserts vorgesehen.

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'); 
+0

Hmm , die Zeilen sind in meinem Browser so nah beieinander, dass einige der Unterstriche nicht angezeigt werden. – Jacob

Antwort

42

Grundsätzlich sind Sie auf dem richtigen Weg - aber Ihnen fehlt eine Quelle aus, wo Sie die Daten zusammenführen möchten - versuchen, etwas wie folgt aus:

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') 
; 

Es gibt keine spezielle Syntax für eine einzelne Zeile MERGE - alles was Sie tun müssen, ist eine richtige Klausel zu verwenden. Mit dieser richtigen Bedingung in der -Klausel können Sie die Quelle auf eine einzelne Zeile begrenzen - kein Problem.

Und vergessen Sie nicht das abschließende Semikolon! Kein Witz - es ist wichtig!

Siehe this blog post für ein wirklich gutes Intro zu MERGE.

+6

Ich habe keine SomeOtherTable. Willst du damit sagen, dass ich eins mit so etwas simulieren muss? VERWENDUNG (SELECT 0 mt_member, 110 mt_topic) als Quelle – Jacob

+0

@Jacob: Sie müssen eine Quelle haben, ja - eine Unterabfrage, wie Sie erwähnen, sollte in Ordnung sein - versuchen Sie es! –

+5

Für alle, die durch diese Antwort verwirrt sind, lesen Sie [diese andere Frage] (http://stackoverflow.com/questions/11216067/what-isusing-in-sql-server-2008-merge-syntax). –

88

Ich habe endlich die Upsert Syntax MERGE in SQL Server 2008 verwenden, was Jacob (ein Upsert) tun wollte:

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' 
    WHERE mt_member = 0 
    AND mt_topic = 110 
END 
ELSE 
BEGIN 
    --insert new row 
    INSERT INTO member_topic (mt_member, mt_topic, mt_notes) 
    VALUES (0, 110, 'test') 
END 

Die äquivalente MERGE Syntax:

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 (foo.mt_member, foo.mt_topic, foo.mt_notes) 
; --A MERGE statement must be terminated by a semi-colon (;). 
+8

In der 'WHEN NOT MATCHED THEN'-Klausel, warum fügen Sie' VALUES (mt_member, mt_topic, mt_notes) 'und nicht' VALUES (foo.mt_member, foo.mt_topic, foo.mt_notes) '' ein? –

+0

@SamP Weil warum nicht? Ist es so, dass SQL Server die Werte von einem * anderen * als der Pseudo-Tabelle 'foo' bekommt? Oh wait ... –

+0

Wird die Zeile "update member_topic SET mt_notes = 'test'" in dem Beispiel für die Nicht-Merge-Beispielaktualisierung _alle_ Zeilen in der Tabelle nicht aktualisiert? Nicht was beabsichtigt war. –

Verwandte Themen