2009-12-23 42 views
28

Tengo una tabla con columnas record_id (auto inc), sender, sent_time y status.¿Cómo INSERTAR un registro o ACTUALIZAR si ya existe?

En caso de que no haya ningún registro de un remitente en particular, por ejemplo "sender1", tengo que INSERTAR un nuevo registro, de lo contrario, tendré que ACTUALIZAR el registro existente que pertenece a "usuario1".

Así que si no hay ningún registro que ya está almacenada, me ejecutar

# record_id is AUTO_INCREMENT field 
INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status) 

de lo contrario habría ejecutar instrucción UPDATE.

De todos modos ... ¿alguien sabe cómo combinar estas dos declaraciones para insertar un nuevo registro si no hay ningún registro donde el valor del remitente del campo es "usuario1", de lo contrario, actualice el registro existente?

Respuesta

45

MySQL soporta la insert-on-duplicate sintaxis, Fe:

INSERT INTO table (key,col1) VALUES (1,2) 
    ON DUPLICATE KEY UPDATE col1 = 2; 
+2

La sintaxis es aún más potente que eso: "ON DUPLICATE KEY ACTUALIZACIÓN col1 = Valores (col1) es una forma más elegante de haga lo que describe (y funciona en inserciones de varias filas). También puede usar el valor de col1, como en ON DUPLICATE KEY UPDATE col1 = col1 + 1. – ojrac

+0

¿por qué hacer col1 = col1 + 1? ¿Qué significa eso? significa? –

+1

Tropezamos con este hilo ... col1 = col1 +1 es un ejemplo en el que tal vez tenga un recuento en su tabla, en lugar de usar SELECT para obtener el valor y agregar 1, hará referencia al valor actual en la tabla, y realice un cálculo haciendo que la instrucción SELECT sea redundante. – tutts

2

Echa un vistazo "Insert on Duplicate Key Update".

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+1

No es cierto - "ON DUPLICATE KEY UPDATE (añadió en MySQL 4.1.0)" – Piskvor

1

Uno opciones está utilizando la sintaxis de actualización duplicado

http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

Otras opciones está haciendo selecto de averiguar si existe registro y luego hacer la inserción/actualizar en consecuencia. Tenga en cuenta que si está realizando una selección de transacciones, no terminará la transacción explícitamente, por lo que es seguro usarla.

3

Como han mencionado otros, debe usar "insertar ... en la actualización de clave duplicada", a veces denominado "upsert". Sin embargo, en su caso específico, no desea utilizar un valor estático en la actualización, sino más bien los valores que transfiere a la cláusula de valores de la instrucción de inserción.

Específicamente, creo que desea actualizar dos columnas si la fila ya existe:

1) sent_time 
2) status 

Con el fin de hacer esto, se utiliza un "upsert" declaración como esta (usando el ejemplo):

INSERT INTO messages (sender, sent_time, status) 
VALUES (@sender, time, @status) 
ON DUPLICATE KEY UPDATE 
    sent_time = values(sent_time), 
    status = values(status); 
11

Si tiene restricciones sólidas en la tabla, entonces también puede usar el REPLACE INTO para eso. He aquí un citan a partir de MySQL:

REPLACE funciona exactamente igual que INSERT, excepto que si un viejo fila de la tabla tiene el mismo valor que una nueva fila para una clave principal o un índice UNIQUE, se suprime la línea de edad antes de que se inserte la nueva fila.

La sintaxis es básicamente el mismo que INSERT INTO, basta con sustituir INSERT por REPLACE.

INSERT INTO messages (sender, sent_time, status) VALUES (@sender, time, @status) 

sería entonces

REPLACE INTO messages (sender, sent_time, status) VALUES (@sender, time, @status) 

Tenga en cuenta que este es un comando específico de MySQL que no ocurre en otra base de datos de, a fin de mantener la portabilidad en mente.

+3

La eliminación de la fila anterior causará complicaciones cuando La fila es padre de muchas otras tablas. Aquellos con eliminación en cascada eliminarán toda la relación. Realmente solo queremos hacer una actualización. –

0
use merge statement : 

merge into T1 
      using T2 
      on (T1.ID = T2.ID) 
    when matched 
    then update set 
         T1.Name = T2.Name 
    when not matched 
    then insert values (T2.ID,T2.Name); 
Cuestiones relacionadas