2012-08-08 17 views
6

Zrobiłem kilka badań, ale nic nie wydaje się pasować do moich potrzeb. Mam tabelę bazy danych, która zawiera niektóre dane pobierane z usługi internetowej.Warunkowo NA DUPLIKACIE KEY UPDATE

Użytkownik wykonuje pewne zadania dla każdego rekordu, a następnie oflaguje go jako "przetworzony". Mam więc dodatkowe pole db (nie oparte na danych, które otrzymuję od WS) o nazwie "przetworzone", domyślnie ustawione na 0, i na 1, gdy użytkownik wykonał swoją pracę.

Każdego dnia sprawdzam WS, a jeśli zmieni się kod statusu, chcę zaktualizować wiersz i przywrócić go do 0 (aby użytkownik mógł ponownie obsłużyć).

Powiedzmy to mój db ...

+------+------------+-------+------------+ 
| id | statuscode | foo | processed | 
+------+------------+-------+------------+ 
| 123 | 66   | bar | 1   | 
+------+------------+-------+------------+ 
  • Jeśli nie jest to rząd z tym samym kluczem (id) Chcę wstawić nowy rekord.
  • Jeśli istnieje wiersz z tym samym kluczem i zmianą "foo", chcę zaktualizować dowolną wartość z wyjątkiem pola "przetworzone".
  • Jeśli istnieje rząd z tym samym zmianę klucza i StatusCode chcę zaktualizować dowolną wartość i zestaw przetwarzane 0.

myślę, że ON duplikat KEY UPDATE z pewnym warunkiem mógłby działać, może z niektórymi CASE lub IF condition ... czy się mylę? Wszelkie sugestie są mile widziane, z góry dzięki!

+0

jak są u zamiar wykryć 'foo 'zmienić? Czy masz wartość dla siebie, aby sprawdzić to przed kolumną foo? – nawfal

Odpowiedz

7

coś takiego (ostrzeżenie: NULL wartości nie załatwione):

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

nie powinno być jeszcze dwóch sprawdzeń dla pól foo i statuscode? – nawfal

+0

@nawfal: Dwa kolejne? czemu? Jeśli 'foo' zmienia się lub nie jest nieistotne, to zajmuje się częścią' ELSE'. –

+0

tylko wtedy, gdy zmienia się kod foo lub status, tylko wtedy chce, aby inne pola mogły być aktualizowane. Zobacz moją odpowiedź, zrozumiałbyś, o czym mówię: – nawfal

1

nieznacznej modyfikacji innej odpowiedzi tutaj, należy to zrobić:

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)