Sé que puede insertar varias filas a la vez, ¿hay alguna manera de actualizar varias filas a la vez (como en una consulta) en MySQL?
Editar: por ejemplo, tengo lo siguiente
Name id Col1 Col2
Row1 1 6 1
Row2 2 2 3
Row3 3 9 5
Row4 4 16 8
Quiero combinar todas las siguientes actualizaciones en una consulta
UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;
mysql
sql
sql-update
Teifion
fuente
fuente
Como tiene valores dinámicos, debe usar un IF o CASE para que las columnas se actualicen. Se pone un poco feo, pero debería funcionar.
Usando su ejemplo, podría hacerlo como:
fuente
$commandTxt = 'UPDATE operations SET chunk_finished = CASE id '; foreach ($blockOperationChecked as $operationID => $operationChecked) $commandTxt .= " WHEN $operationID THEN $operationChecked "; $commandTxt .= 'ELSE id END WHERE id IN ('.implode(', ', array_keys(blockOperationChecked )).');';
La pregunta es antigua, pero me gustaría ampliar el tema con otra respuesta.
Mi punto es que la forma más fácil de lograrlo es simplemente envolver múltiples consultas con una transacción. La respuesta aceptada
INSERT ... ON DUPLICATE KEY UPDATE
es un buen truco, pero uno debe tener en cuenta sus inconvenientes y limitaciones:"Field 'fieldname' doesn't have a default value"
advertencia de MySQL incluso si no inserta una sola fila. Te meterá en problemas si decides ser estricto y convertir las advertencias de mysql en excepciones de tiempo de ejecución en tu aplicación.Hice algunas pruebas de rendimiento para tres de las variantes sugeridas, incluida la
INSERT ... ON DUPLICATE KEY UPDATE
variante, una variante con la cláusula "caso / cuándo / entonces" y un enfoque ingenuo con la transacción. Puede obtener el código de Python y los resultados aquí . La conclusión general es que la variante con declaración de caso resulta ser el doble de rápida que otras dos variantes, pero es bastante difícil escribir un código correcto y seguro para la inyección, por lo que personalmente me quedo con el enfoque más simple: usar transacciones.Editar: Los resultados de Dakusan prueban que mis estimaciones de rendimiento no son del todo válidas. Vea esta respuesta para otra investigación más elaborada.
fuente
No estoy seguro de por qué todavía no se menciona otra opción útil:
fuente
Todo lo siguiente se aplica a InnoDB.
Siento que conocer las velocidades de los 3 métodos diferentes es importante.
Hay 3 métodos:
Acabo de probar esto, y el método INSERT fue 6.7 veces más rápido para mí que el método TRANSACTION. Probé en un conjunto de 3.000 y 30.000 filas.
El método TRANSACTION todavía tiene que ejecutar cada consulta individualmente, lo que lleva tiempo, aunque agrupa los resultados en la memoria, o algo así, mientras se ejecuta. El método de TRANSACCIÓN también es bastante costoso tanto en la réplica como en los registros de consultas.
Peor aún, el método CASE fue 41.1x más lento que el método INSERT con 30,000 registros (6.1x más lento que TRANSACTION). Y 75 veces más lento en MyISAM. Los métodos INSERT y CASE rompieron incluso a ~ 1,000 registros. Incluso con 100 registros, el método CASE es MUCHO más rápido.
Entonces, en general, creo que el método INSERT es el mejor y el más fácil de usar. Las consultas son más pequeñas y fáciles de leer y solo requieren 1 consulta de acción. Esto se aplica tanto a InnoDB como a MyISAM.
Cosas de bonificación:
La solución para el problema de la no-default-campo es INSERT para desactivar temporalmente los modos SQL pertinentes:
SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES","")
. Asegúrese de guardar elsql_mode
primero si planea revertirlo.En cuanto a otros comentarios que he visto que dicen que el auto_increment aumenta usando el método INSERT, este parece ser el caso en InnoDB, pero no en MyISAM.
El código para ejecutar las pruebas es el siguiente. También genera archivos .SQL para eliminar la sobrecarga del intérprete php
fuente
Usa una mesa temporal
fuente
Esto debería funcionar para ti.
Hay una referencia en el manual de MySQL para varias tablas.
fuente
¿Por qué nadie menciona múltiples declaraciones en una consulta ?
En php, utiliza el
multi_query
método de instancia mysqli.Del manual de php
Aquí está el resultado en comparación con otros 3 métodos en la actualización 30,000 sin formato. El código se puede encontrar aquí, que se basa en la respuesta de @Dakusan
Transacción: 5.5194580554962
Insertar: 0.20669293403625
Caso: 16.474853992462
Multi: 0.0412278175354
Como puede ver, la consulta de múltiples declaraciones es más eficiente que la respuesta más alta.
Si recibe un mensaje de error como este:
Es posible que deba aumentar el
max_allowed_packet
archivo de configuración in mysql que está en mi máquina/etc/mysql/my.cnf
y luego reiniciar mysqld.fuente
$mysqli->multi_query($sql)
tomó "0" segundos. Sin embargo, las consultas posteriores fallaron, lo que hizo que este fuera un "programa" separado.Hay una configuración que puede modificar llamada 'declaración múltiple' que deshabilita el 'mecanismo de seguridad' de MySQL implementado para prevenir (más de un) comando de inyección. Típico de la implementación 'brillante' de MySQL, también evita que el usuario realice consultas eficientes.
Aquí ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) hay información sobre la implementación en C de la configuración.
Si está usando PHP, puede usar mysqli para hacer múltiples declaraciones (creo que php se ha enviado con mysqli por un tiempo ahora)
Espero que ayude.
fuente
mysqli::begin_transaction(..)
antes de enviar la consulta ymysql::commit(..)
después. O useSTART TRANSACTION
como primera yCOMMIT
última declaración en la consulta misma.Puede crear un alias en la misma tabla para proporcionarle los identificadores que desea insertar (si está realizando una actualización fila por fila:
Además, debería parecer obvio que también puede actualizar desde otras tablas. En este caso, la actualización se dobla como una instrucción "SELECCIONAR", proporcionándole los datos de la tabla que está especificando. Está indicando explícitamente en su consulta los valores de actualización, por lo que la segunda tabla no se ve afectada.
fuente
También puede estar interesado en usar combinaciones en las actualizaciones, que también es posible.
Editar: si los valores que está actualizando no provienen de otro lugar de la base de datos, deberá emitir múltiples consultas de actualización.
fuente
Y ahora la manera fácil
fuente
utilizar
Tenga en cuenta:
fuente
Lo siguiente actualizará todas las filas en una tabla
El siguiente actualizará todas las filas donde el valor de Column2 es más de 5
Hay todos los ejemplos de Unkwntech de actualizar más de una tabla
fuente
Sí ... es posible usando INSERTAR EN LA ACTUALIZACIÓN DE CLAVE DUPLICADA declaración sql ... sintaxis: INSERTAR EN nombre_tabla (a, b, c) VALORES (1,2,3), (4,5,6) EN LA ACTUALIZACIÓN DE CLAVE DUPLICADA a = VALORES (a), b = VALORES (b), c = VALORES (c)
fuente
Esto debería lograr lo que estás buscando. Simplemente agregue más id. Lo he probado
fuente
// Simplemente lo construyes en php como
Para que pueda actualizar la tabla de agujeros con una consulta
fuente
something
asomething
)