2012-08-08 39 views
6

He hecho algunas investigaciones, pero nada parece satisfacer mis necesidades. Tengo una tabla de base de datos que contiene algunos datos recuperados de un servicio web.Condicional ON DUPLICATE KEY UPDATE

Un usuario realiza algunas tareas para cada registro y luego lo marca como "procesado". Así que tengo un campo db adicional (no basado en los datos que obtengo del WS) llamado "procesado" que se establece en 0 por defecto, y a 1 cuando el usuario ha hecho su trabajo.

Cada día reviso el WS, y si el código de estado cambia, quiero actualizar la fila y volver a procesarla en 0 (para que el usuario pueda manejarla de nuevo).

Digamos que este es mi db ...

+------+------------+-------+------------+ 
| id | statuscode | foo | processed | 
+------+------------+-------+------------+ 
| 123 | 66   | bar | 1   | 
+------+------------+-------+------------+ 
  • Si no hay una fila con la misma clave (id) Quiero insertar un nuevo registro.
  • Si hay una fila con la misma clave y un cambio 'foo', quiero actualizar cualquier valor excepto el campo 'procesado'.
  • Si hay una fila con el mismo cambio de clave y statuscode quiero actualizar cualquier valor o ajuste el procesado a 0.

Creo que EN DUPLICADO KEY UPDATE con alguna condición podría hacer que funcione, tal vez con un poco de CASO o condición IF ... ¿estoy equivocado? Cualquier sugerencia es bienvenida, ¡gracias de antemano!

+0

how are u va a detectar 'fu '¿cambio? ¿Tiene un valor para usted mismo para verificarlo contra la columna foo? – nawfal

Respuesta

7

Algo como esto (advertencia: NULL valores no se atiende):

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

¿no debería haber dos controles más para los campos foo y statuscode? – nawfal

+0

@nawfal: ¿dos más? ¿por qué? Si 'foo' cambia o no es irrelevante, se ocupa de la parte' ELSE'. –

+0

solo si cambian foo o statuscode, solo entonces quiere que otros campos sean actualizables. Ver mi respuesta, entendería de lo que estoy hablando – nawfal

1

Ligera modificación de otra respuesta aquí, esto debería hacer:

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) 
Cuestiones relacionadas