Pregunta

Es necesario actualizar dos tablas dentro de una sola transacción. Las consultas individuales tienen el siguiente aspecto:

1. INSERT INTO t1 (col1, col2) 
   VALUES (val1, val2) 
   ON DUPLICATE KEY 
      UPDATE col2 = val2;

Si la consulta anterior provoca una inserción entonces necesito para ejecutar la siguiente declaración en la segunda tabla:

2. INSERT INTO t2 (col1, col2) 
   VALUES (val1, val2) 
   ON DUPLICATE KEY  
      UPDATE col2 = col2 + val2;

lo contrario,

3. UPDATE t2 
       SET col2 = col2 - old_val2 + val2 
     WHERE col1 = val1; 
   -- old_val2 is the value of 
      t1.col2 before it was updated

En este momento me encuentro un SELECT en t1 en primer lugar, para determinar si la declaración 1 provocará una inserción o actualización en t1. Luego ejecutar declaración 1 y cualquiera de 2 y 3 dentro de una transacción. ¿Cuáles son las formas en que puedo hacer todo esto dentro de una misma transacción?

El enfoque que estaba pensando es la siguiente:

UPDATE t2, t1 
   set t2.col2 = t2.col2 - t1.col2 
 WHERE t1.col1 = t2.col2 
   and t1.col1 = val1;

INSERT INTO t1 (col1, col2) 
VALUES (val1, val2) 
ON DUPLICATE KEY 
   UPDATE col2 = val2;

INSERT INTO t2, t1 (t2.col1, t2.col2) 
VALUES (t1.col1, t1.col2) 
ON DUPLICATE KEY 
   UPDATE t2.col2 = t2.col2 + t1.col2 
WHERE t1.col1 = t2.col2 
  and t1.col1 = val1;

Por desgracia, no hay mesas múltiples INSERT ... EN ACTUALIZACIÓN una llave duplicada en MySQL 5.0. ¿Qué otra cosa podía hacer?

¿Fue útil?

Solución 2

Está bien, así que tengo esta resuelto y hecho de una manera que me gusta:

 UPDATE t2, t1 
   SET t2.col2 = t2.col2 - t1.col2 
 WHERE t1.col1 = t2.col2 
   AND t1.col1 = val1;

INSERT INTO t1 (col1, col2) VALUES (val1, val2) 
ON DUPLICATE KEY UPDATE
   col2 = val2;

INSERT INTO t2 (col1, col2) VALUES (val1, val2) 
ON DUPLICATE KEY UPDATE
   col2 = col2 + VALUES(col2);

La tercera consulta puede ser reescrita para referirse a los valores de t1 como tales:

INSERT INTO t2 (col1, col2)
   SELECT col1, col2 FROM t1 WHERE col1 = val1
ON DUPLICATE KEY UPDATE
   t2.col2 = t2.col2 + VALUES(col2);

Otros consejos

Si se ejecuta una INSERT o un UPDATE, el cliente es capaz de buscar el número de filas que cambió. La forma de hacerlo depende de su cliente, pero para varios lenguajes de programación, este número es devuelto por su INSERT si tuvo éxito.

Si se ejecuta INSERT...ON DUPLICATE KEY UPDATE, puede así traes este número, pero no es exactamente lo que esperas que sea. Si inserta / actualiza una sola fila, recibirá 1 como el número de filas que cambia en caso de una INSERT y 2 en caso de una UPDATE, a pesar de que sólo hay una fila que ha cambiado. Se podría utilizar este número para decidir sobre el lado del cliente, que consulta se ejecute siguiente.

No es tan bonito como una sola transacción, pero al menos a deshacerse de uno SELECT.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top