2009-12-23 12 views
28

Ich habe eine Tabelle mit Spalten record_id (auto inc), sender, sent_time und status.Wie fügt man einen Datensatz oder UPDATE ein, wenn er bereits existiert?

Wenn es keinen Datensatz eines bestimmten Absenders gibt, zum Beispiel "sender1", muss ich einen neuen Datensatz einfügen, ansonsten muss ich den vorhandenen Datensatz aktualisieren, der zu "user1" gehört.

Also, wenn es keine Datensatz bereits gespeichert ist, würde ich ausführen

# record_id is AUTO_INCREMENT field 
INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status) 

Sonst würde ich UPDATE-Anweisung ausführen.

Wie auch immer .. weiß jemand diese beiden Aussagen zu kombinieren, um einen neuen Datensatz einzufügen, wenn es keinen Datensatz gibt, bei dem der Feldabsenderwert "user1" ist, ansonsten den vorhandenen Datensatz aktualisieren?

Antwort

45

MySQL unterstützt die insert-on-duplicate Syntax, zB:

INSERT INTO table (key,col1) VALUES (1,2) 
    ON DUPLICATE KEY UPDATE col1 = 2; 
+2

Die Syntax ist noch leistungsfähiger als das: „ON DUPLICATE KEY UPDATE col1 = VALUES (col1) ist ein eleganter Weg, um tue, was du beschreibst (und es funktioniert bei mehrzeiligen Einfügungen.) Du kannst auch den Wert von col1 verwenden, wie bei ON DUPLICATE KEY UPDATE col1 = col1 + 1. – ojrac

+0

Warum machst du col1 = col1 + 1. Was macht das? bedeuten? –

+1

über diesen Thread gestolpert ... col1 = col1 1 ist ein Beispiel, wo Sie vielleicht einen Zähler in der Tabelle haben, anstatt mit SELECT, um den Wert zu erhalten, und fügen Sie 1, wird der aktuelle Wert in der Tabelle verweisen, und führen Sie eine Berechnung durch, die die SELECT-Anweisung überflüssig macht – tutts

2

Auschecken "Insert on Duplicate Key Update".

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+1

Nicht wahr - "ON DUPLICATE KEY UPDATE (hinzugefügt in MySQL 4.1.0)" – Piskvor

1

One Optionen verwendet auf doppelte Update Syntax

http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

Andere Optionen wählen tut Datensatz, um herauszufinden, wenn vorhanden und dann insert/update entsprechend. Beachten Sie, dass die Transaktion nicht explizit beendet wird, wenn Sie mit der Transaktion arbeiten.

3

Wie andere bereits erwähnt haben, sollten Sie "Einfügen ... bei Duplikat-Schlüsselaktualisierung" verwenden, manchmal auch als "Upsert" bezeichnet. In Ihrem speziellen Fall möchten Sie jedoch keinen statischen Wert im update verwenden, sondern die Werte, die Sie an die values-Klausel der insert-Anweisung übergeben.

Insbesondere, ich glaube, Sie zwei Spalten aktualisiert werden soll, wenn die Zeile bereits vorhanden ist:

1) sent_time 
2) status 

Um dies zu tun, würden Sie ein „UPSERT“ Anweisung wie folgt verwenden (Ihrem Beispiel verwenden):

INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status) 
ON DUPLICATE KEY UPDATE 
    sent_time = values(sent_time), 
    status = values(status); 
11

Wenn Sie feste Bedingungen für die Tabelle haben, können Sie auch die REPLACE INTO dafür verwenden. Hier ist ein zitieren von MySQL:

REPLACE funktioniert genau wie INSERT, mit der Ausnahme, dass, wenn eine alte Zeile in der Tabelle für einen Primärschlüssel den gleichen Wert wie eine neue Zeile hat oder einen eindeutigen Index, die alte Zeile gelöscht bevor die neue Zeile eingefügt wird.

Die Syntax ist im Grunde das gleiche wie INSERT INTO Ersetzen nur durch INSERTREPLACE.

INSERT INTO messages (sender, sent_time, status) VALUES (@sender, time, @status) 

würde dann

REPLACE INTO messages (sender, sent_time, status) VALUES (@sender, time, @status) 

Hinweis sein, dass dies ein MySQL-spezifischer Befehl ist, die in anderer DB, also halten Portabilität im Gedächtnis nicht auftritt.

+3

Wenn Sie die alte Zeile löschen, kann das zu Komplikationen führen Die Zeile ist ein Elternteil vieler anderer Tabellen. Diejenigen mit Kaskadenlöschung löschen alle Beziehungen. Wir wollen einfach nur updaten. –

0
use merge statement : 

merge into T1 
      using T2 
      on (T1.ID = T2.ID) 
    when matched 
    then update set 
         T1.Name = T2.Name 
    when not matched 
    then insert values (T2.ID,T2.Name);