2012-08-08 8 views
6

Ich habe etwas recherchiert, aber nichts scheint meine Bedürfnisse zu erfüllen. Ich habe eine Datenbanktabelle, die einige Daten enthält, die von einem Webservice abgerufen werden.Bedingte ON DUPLICATE KEY UPDATE

Ein Benutzer führt einige Aufgaben für jeden Datensatz aus und kennzeichnet sie dann als "verarbeitet". Also habe ich ein zusätzliches db-Feld (nicht basierend auf Daten, die ich von der WS bekomme) namens "verarbeitete", die standardmäßig auf 0 gesetzt ist, und auf 1, wenn der Benutzer seine Arbeit erledigt hat.

Jeden Tag überprüfe ich die WS, und wenn der Statuscode ändern möchte ich die Zeile aktualisieren und zurückgesetzt auf 0 (so Benutzer kann es wieder verarbeiten).

Lasst uns sagen, dass dies meine db ist ...

+------+------------+-------+------------+ 
| id | statuscode | foo | processed | 
+------+------------+-------+------------+ 
| 123 | 66   | bar | 1   | 
+------+------------+-------+------------+ 
  • Wenn mit dem gleichen Schlüssel (id) i einen neuen Rekord wollen nicht eine Zeile gibt es einzufügen.
  • Wenn es eine Zeile mit dem gleichen Schlüssel und 'foo' Änderung gibt, ich möchte jeden Wert außer dem 'verarbeiteten' Feld aktualisieren.
  • Wenn es eine Zeile mit dem gleichen Schlüssel und Statusänderung ist i einen Wert aktualisieren möchten, und zu verarbeitende 0.

Ich denke, dass ON DUPLICATE KEY UPDATE mit einer gewissen Bedingung könnte es vielleicht funktioniert, mit einigen CASE oder IF Bedingung ... liege ich falsch? Jeder Vorschlag ist willkommen, danke im Voraus!

+0

wie wollen u 'foo erkennen 'Veränderung? Haben Sie einen Wert für sich selbst, um es gegen foo Spalte zu überprüfen? – nawfal

Antwort

7

So etwas wie diese (Warnung: NULL Werte nicht gepflegt):

INSERT INTO tableX 
    (id, statuscode, foo, processed) 
VALUES 
    (?, ?, ?, DEFAULT) 
ON DUPLICATE KEY UPDATE 
    processed = CASE WHEN statuscode <> VALUES(ststuscode) 
        THEN 0 
        ELSE processed 
       END 
, statuscode = VALUES(statuscode) 
, foo = VALUES(foo) ; 
+0

sollte es nicht zwei weitere Überprüfung für Felder Foo und Statuscode geben? – nawfal

+0

@ Nawfal: Zwei mehr? Warum? Wenn 'foo' sich ändert oder nicht irrelevant ist, wird es durch den' ELSE' Teil beachtet. –

+0

nur wenn foo oder statuscode geändert wird, nur dann, wenn andere Felder aktualisiert werden sollen. Sehen Sie meine Antwort, Sie würden verstehen, worüber ich spreche – nawfal

1

leichte Modifikation einer anderen Antwort hier, sollte dies tun:

INSERT INTO tableX (id, statuscode, foo, processed) 
      VALUES (@id, @statuscode, @foo, @processed) 
ON DUPLICATE KEY UPDATE 
         foo = IF (statuscode != VALUES(statuscode) OR foo != VALUES(foo), VALUES(foo), foo), 
         statuscode = IF (statuscode != VALUES(statuscode) OR foo != VALUES(foo), VALUES(statuscode), statuscode), 
         processed = IF (statuscode != VALUES(statuscode), 0, processed)