Insertar en una tabla MySQL o actualizar si existe

Quiero agregar una fila a una tabla de base de datos, pero si existe una fila con la misma clave única, quiero actualizar la fila.

Por ejemplo:

INSERT INTO table_name (ID, NAME, AGE) VALUES(1, "A", 19);

Digamos que la clave única es IDy en mi base de datos, hay una fila con ID = 1. En ese caso, quiero actualizar esa fila con estos valores. Normalmente esto da un error.
Si uso INSERT IGNORE ignorará el error, pero aún así no se actualizará.

preguntado el 17 de noviembre de 10 a las 11:11

SQL necesita una sintaxis oficial para este caso de uso que no fuerce la duplicación de valores en la sintaxis y conserve la clave principal. -

Para obtener la identificación influenciada, consulte MySQL EN CLAVE DUPLICADA - ¿Última identificación de inserción? -

Advertencia: a partir de la versión 5.7, este enfoque no admite directamente la cláusula WHERE como parte de la operación INSERT / UPDATE. Además, una ACTUALIZACIÓN en realidad cuenta como dos operaciones separadas (ELIMINAR e INSERTAR) ... en caso de que sea importante para fines de auditoría. (Learnbit) -

11 Respuestas

Utiliza la INSERT ... ON DUPLICATE KEY UPDATE

CONSULTA:

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name="A", age=19

contestado el 12 de mayo de 17 a las 06:05

+1 Por lo que he encontrado, este método es menos problemático para las claves de incremento automático y otras colisiones de claves únicas que REPLACE INTO, y es más eficiente. - andres ensley

Sé que todos ustedes aluden a esto, pero quiero ser explícito para los demás. Si la ID que inserta NO es la LLAVE PRIMARIA o ÚNICA, esto no funcionará. Inicialmente, esto no funcionó para mí porque mi identificación no era única. - Keven

me pregunto porque affected row count resultados en 2 al actualizar con éxito (en clave duplicada) una sola fila? ¿Alguien más tuvo este resultado? (Los datos se actualizan correctamente: lo que significa que solo se actualiza 1 fila) - dimitry k

Esto es un poco tarde, pero de todos modos: se dice en el manual que se actualiza en ON DUPLICATE KEY UPDATE aumentar las filas afectadas en 2. Informa 0 si no se actualiza nada (igual que el habitual UPDATE). - Vatev

También tenga en cuenta que puede usar VALUES (nombre) para hacer referencia al valor que intenta insertar, por ejemplo, INSERT INTO table (id, name, age) VALUES (1, "A", 19) ON DUPLICATE KEY UPDATE name = VALUES (name) , edad = VALORES (edad) - Sam el curioso

Echa un vistazo a REPLACE

http://dev.mysql.com/doc/refman/5.0/en/replace.html

REPLACE into table (id, name, age) values(1, "A", 19)

respondido 17 nov., 10:14

@Piontek Porque este es más corto y más fácil de entender y nadie explicó por qué es mejor "insertar en duplicado". - Sr_Chimpancé

cambia las identificaciones del registro y, por lo tanto, puede destruir referencias extranjeras. - BOH

El otro problema con REPLACE INTO es que debe: especifique valores para TODOS los campos ... de lo contrario, los campos se perderán o se reemplazarán con los valores predeterminados. REEMPLAZAR EN esencialmente elimina la fila si existe, e inserta la nueva fila. En el ejemplo, si hiciera 'REPLACE INTO table (id, age) values ​​(1, 19), el campo de nombre se volvería nulo. - Dale

En realidad, esto es BORRAR toda la fila y realizar una nueva INSERCIÓN. - mjb

@mjb Por lo tanto, debe tener privilegios DELETE, que es mejor no tener si no los necesita. El usuario de la base de datos de mi entorno solo tiene permisos INSERTAR y ACTUALIZAR, por lo que REEMPLAZAR no funcionará. - ndm13

Cuando utilice la inserción por lotes, utilice la siguiente sintaxis:

INSERT INTO TABLE (id, name, age) VALUES (1, "A", 19), (2, "B", 17), (3, "C", 22)
ON DUPLICATE KEY UPDATE
    name = VALUES (name),
    ...

Respondido el 27 de enero de 17 a las 12:01

If VALUES(name) no funciona, puedes intentarlo name = 'name_value',...; - hijo pham

Cualquiera de estas soluciones funcionará con respecto a su pregunta:

INSERT IGNORE INTO table (id, name, age) VALUES (1, "A", 19);

or

INSERT INTO TABLE (id, name, age) VALUES(1, "A", 19) 
    ON DUPLICATE KEY UPDATE NAME = "A", AGE = 19;  

or

REPLACE INTO table (id, name, age) VALUES(1, "A", 19);

Si quieres saber en detalle sobre esta declaración visite este enlace

Respondido el 11 de enero de 21 a las 14:01

REPLACE no está documentado en el documento vinculado. - ray baxter

consultas sql llenas de errores tipográficos, sus ejemplos no funcionarán. Es INSERT INTO TABLE (no INTO TABLE) y ON DUPLICATE KEY UPDATE (no EN DUPLICATE UPDATE SET). No estoy seguro de quién vota a favor de esto: Robert Sinclair

Perdón por el error tipográfico. Gracias por corregirme - dilraj singh

¿Cómo INSERT IGNORE trabajará aquí? Simplemente ignora el error de inserción y NO realiza la actualización, por lo que de ninguna manera puede tratarse como una respuesta a la pregunta OP. - RAM237

Probar esto:

INSERT INTO table (id, name, age) VALUES (1, 'A', 19) ON DUPLICATE KEY UPDATE id = id + 1;

Espero que esto ayude.

respondido 17 nov., 10:14

en realidad, no necesito agregar los nuevos valores a otra fila con una nueva ID, sino que quiero reemplazar los valores existentes de id = 1 con estos valores. (según tengo entendido, esto aumenta la identificación y agrega los datos) - Keshan

No creo que quiera aumentar la identificación en uno en duplicados. - Donnie

"transgredir" no es la palabra que estás buscando :) Desafortunadamente, ahora que he visto "transgredir", ya no puedo visualizar la palabra real .. - mwfearnley

¿Buscaba "travesías" o "cubiertas"? - chris dev

@mwfearnley La palabra que intentaba visualizar es "trasciende". Solo tomó un año y medio :-) - miguel krebs

Prueba esto:

INSERT INTO table (id,name,age) VALUES('1','Mohammad','21') ON DUPLICATE KEY UPDATE name='Mohammad',age='21'

Nota:
Aquí, si id es la clave principal, luego de la primera inserción con id='1' cada vez que intente insertar id='1' actualizará el nombre y la edad y la edad anterior del nombre cambiará.

Respondido 27 ago 14, 09:08

Quiero trabajar sin usar id. ¿Lo ha intentado sin clave principal? - ersks

@ersks ve la pregunta. al usuario se le preguntó sobre cuándo hay una clave única - Rasel

Lo entendí, pero estoy tratando de resolver mi problema en el que se conocen estos únicos valores. Entonces, en tal situación, escribí el comentario anterior con la esperanza de una solución correcta. - ersks

Al usar SQLite:

REPLACE into table (id, name, age) values(1, "A", 19)

Siempre que id es la clave principal. O simplemente inserta otra fila. Ver INSERT (SQLite).

Respondido el 08 de enero de 17 a las 13:01

Qué replace into lo que hace es exactamente "insertar o actualizar cuando exista". @Búho - DawnScan

+1 (1 de 3) Descubrí que esto funcionaba para mi situación: necesitaba reemplazar una fila existente con una clave única o, si no está allí, agregar la fila. La solución más simple aquí. - robyouknow

(2 de 3) Mi consulta: CREATE TRIGGER worklog_update AFTER INSERT ON worklog FOR EACH ROW REPLACE INTO support_time_monthly_hours ( ProjectID, monthTotalTime, Year, Month ) SELECT jiraissue.PROJECT, SUM(worklog.timeworked), YEAR(CURRENT_DATE()), MONTH(CURRENT_DATE()) FROM worklog, jiraissue WHERE worklog.issueid = jiraissue.ID AND jiraissue.PROJECT = (SELECT PROJECT FROM jiraissue WHERE NEW.issueid = jiraissue.ID ) AND worklog.startdate BETWEEN DATE_FORMAT(NOW() ,'%Y-%m-01 00:00:00') AND NOW(); - robyouknow

(3 de 3) Pregunta / respuesta relacionada stackoverflow.com/questions/41767517/… - robyouknow

El problema con esto en mysql es que replace eliminará otros valores en caso de que no se proporcionen. Sin embargo, la solución @ fabiano-souza es más apropiada - quamber ali

Solo porque estaba aquí buscando esta solución pero para actualizar desde otra tabla estructurada de manera idéntica (en mi caso, el sitio web prueba la base de datos a la base de datos en vivo):

INSERT  live-db.table1
SELECT  *
FROM    test-db.table1 t
ON DUPLICATE KEY UPDATE
        ColToUpdate1 = t.ColToUpdate1,
        ColToUpdate2 = t.ColToUpdate2,
        ...

Como se mencionó en otra parte, solo las columnas que desea actualizar deben incluirse después ON DUPLICATE KEY UPDATE.

No es necesario enumerar las columnas en el INSERT or SELECT, aunque estoy de acuerdo en que probablemente sea una mejor práctica.

Respondido el 09 de junio de 17 a las 06:06

En caso de que quisieras hacer un non-primary campos como criterio / condición para ON DUPLICATE, puedes hacer un UNIQUE INDEX en esa mesa para activar el DUPLICATE.

ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`);

Y en caso de que desee combinar dos campos para hacerlo único en la tabla, puede lograrlo agregando más en el último parámetro.

ALTER TABLE `table` ADD UNIQUE `unique_index`(`name`, `age`);

Tenga en cuenta, solo asegúrese de eliminar primero todos los datos que tienen el mismo name y age valor en las otras filas.

DELETE table FROM table AS a, table AS b WHERE a.id < b.id 
AND a.name <=> b.name AND a.age <=> b.age;

Después de eso, debería activar el ON DUPLICATE evento.

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name = VALUES(name), age = VALUES(age)

contestado el 22 de mayo de 20 a las 06:05

Lo he intentado, obtengo un error que dice "Columna BLOB / TEXT 'nombre_columna' utilizada en la especificación de clave sin una longitud de clave" - Natalia

@Natalia amablemente crea un dbviolín para que pueda comprobar - Rico

Lo intentaré, pero básicamente, no se puede hacer que el tipo de texto de una columna sea único en MySQL. Lo hice varchar. - Natalia

En mi caso, creé las consultas a continuación, pero en la primera consulta si id 1 ya existe y la edad ya está allí, después de eso, si crea la primera consulta sin age que el valor de age no habrá ninguno

REPLACE into table SET `id` = 1, `name` = 'A', `age` = 19

para evitar el problema anterior, cree una consulta como la siguiente

INSERT INTO table SET `id` = '1', `name` = 'A', `age` = 19 ON DUPLICATE KEY UPDATE `id` = "1", `name` = "A",`age` = 19

que te ayude ...

Respondido 05 Feb 19, 10:02

¿Alguien sabe por qué debemos asignar los valores dos veces? ¿Por qué MySQL no nos permite finalizar la consulta en ON DUPLICATE KEY UPDATE sin duplicar todas las declaraciones de asignación? Algunas tablas de bases de datos tienen muchas columnas, y esto parece redundante / gratuito. Entiendo por qué tenemos la opción de realizar asignaciones alternativas, pero ¿por qué no tener la opción de omitirlas también? Solo curiosidad por saber si alguien lo sabe. - Blue Water

En caso de que desee mantener el campo antiguo (por ejemplo: nombre). La consulta será:

INSERT INTO table (id, name, age) VALUES(1, "A", 19) ON DUPLICATE KEY UPDATE    
name=name, age=19;

Respondido 16 ago 19, 06:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.