Insertar tabla MySql si no existe, de lo contrario, actualice


105
UPDATE AggregatedData SET datenum="734152.979166667", 
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";

Funciona si datenumexiste, pero quiero insertar estos datos como una nueva fila si datenumno existe.

ACTUALIZAR

el datenum es único pero esa no es la clave principal


2
¿Es "datenum" único? Puede usar INSERT ... ON DUPLICATE KEY UPDATE si es así.
Jacob

Respuestas:


143

Jai tiene razón en que debes usar INSERT ... ON DUPLICATE KEY UPDATE.

Tenga en cuenta que no necesita incluir datenum en la cláusula de actualización ya que es la clave única, por lo que no debería cambiar. Debe incluir todas las demás columnas de su tabla. Puede utilizar la VALUES()función para asegurarse de que se utilizan los valores adecuados al actualizar las otras columnas.

Aquí está su actualización reescrita usando la INSERT ... ON DUPLICATE KEY UPDATEsintaxis adecuada para MySQL:

INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE 
  Timestamp=VALUES(Timestamp)

18
Tenga cuidado al usar INSERT ... ON DUPLICATE KEY UPDATE en tablas contra una tabla que tiene más de una clave única o principal. Tomado de la documentación de MySQL : Además, comenzando con MySQL 5.5.24, una instrucción INSERT ... ON DUPLICATE KEY UPDATE contra una tabla que tiene más de una clave única o primaria también se marca como insegura. (Error # 11765650, Error # 58637) Descripción del error 58637 bugs.mysql.com/bug.php?id=58637
banda ancha

1
Podría ser necesario crear una UNIQUErestricción Timestampmediante el uso deALTER TABLE AggregatedData ADD UNIQUE (Timestamp)
Avyakt

@broadband, puede usar una clave compuesta para evitar este error
Kareem

16

Intente usar esto :

Si especifica ON DUPLICATE KEY UPDATE, y se inserta una fila que causaría un valor duplicado en una ACTUALIZACIÓN UNIQUE index orDE CLAVE , MySQL performs an [PRIMARIA`] ( http://dev.mysql.com/doc/refman/5.7/en/update.html ) de la fila anterior. ..

La ON DUPLICATE KEY UPDATEcláusula puede contener varias asignaciones de columnas, separadas por comas.

Con ON DUPLICATE KEY UPDATE, el valor de las filas afectadas por fila es 1 si la fila se inserta como una fila nueva, 2 si se actualiza una fila existente y 0 si una fila existente se establece en sus valores actuales. Si especifica la CLIENT_FOUND_ROWSbandera a mysql_real_connect()cuando se conecta a mysqld , el valor de las filas afectadas es 1 (no 0) si una fila existente se establece en sus valores actuales ...


Pero mi datenum no es la clave principal.
OHLÁLÁ

Entonces, en mi caso, cuál es la solución, probé esta, sin ninguna solución: INSERT INTO forwind.aggregateddata (datenum, Timestamp, Min_F1_baro_20_) VALUES ('1', '2', '3') ON DUPLICATE KEY UPDATE datenum = datenum;
OHLÁLÁ

1
¿Se supone que el datenum es único? Si es así, agregue un índice único (si aún no lo ha agregado) Entonces funcionará. Consulte dev.mysql.com/doc/refman/5.1/en/alter-table.html para saber cómo anunciar índices ÚNICOS
Jai

ahora definí el datenum como único, y funciona bien, gracias
OHLÁLÁ

1
Solo un enlace, tal vez dé una respuesta.
Andrew

0

Tuve una situación en la que necesitaba actualizar o insertar en una tabla de acuerdo con dos campos (ambas claves externas) en los que no podía establecer una restricción ÚNICA (por lo que INSERT ... ON DUPLICATE KEY UPDATE no funcionará). Esto es lo que terminé usando:

replace into last_recogs (id, hasher_id, hash_id, last_recog) 
  select l.* from 
    (select id, hasher_id, hash_id, [new_value] from last_recogs 
     where hasher_id in (select id from hashers where name=[hasher_name])
     and hash_id in (select id from hashes where name=[hash_name]) 
     union 
     select 0, m.id, h.id, [new_value] 
     from hashers m cross join hashes h 
     where m.name=[hasher_name] 
     and h.name=[hash_name]) l 
  limit 1;

Este ejemplo se extrajo de una de mis bases de datos, con los parámetros de entrada (dos nombres y un número) reemplazados por [hasher_name], [hash_name] y [new_value]. El SELECT ... LIMIT 1 anidado extrae el primero del registro existente o un nuevo registro (last_recogs.id es una clave primaria de autoincremento) y lo usa como entrada de valor en REPLACE INTO.


REPLACE inserta siempre una nueva fila. simplemente elimina el original, ya existente.
jasie
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.