INSERTAR MYSQL o ACTUALIZAR SI

He estado buscando por la web por un time y no parezco encontrar nada similar a lo que quiero. Sé que tiene algo que ver con la forma en que estoy escribiendo mi consulta, pero cualquier ayuda sería apreciada.

Lo básico de lo que estoy tratando de hacer es:

  • Inserta algunos elementos en una tabla si no existe
  • Actualiza un artículo si existe

Existe en el formatting:

nombre, código de barras, artículo, cantidad, location, precio y date

nombre – se puede usar en varias filas código de barras – es para un artículo específico pero se puede usar como varias ubicaciones artículo – es lo mismo que código de barras pero contiene la cantidad de nombre – location autoexplicativa – este puede ser el precio de diferentes ubicaciones – que se adjunta a una date de artículo específico: la última vez que se compró ese artículo

Lo más complicado es que un "nombre" puede tener varios elementos (código de barras y artículo) en diferentes lugares a precios diferentes. La idea es que un cliente pueda ver cuánto compraron un artículo en un momento determinado, para saber cuánto necesitarían venderlo.

Sin embargo, el precio al que lo compraron puede variar, por lo que deben crear otra fila en la tabla si el precio es diferente de una compra anterior.

La idea detrás de todo es que registre cuánto tiene un "nombre" de cada artículo en cada location y luego el precio en que lo compraron y cuándo lo compraron por última vez.

Espero que tenga sentido.

En código psuedo:

Insert into table if does not exist - name, barcode, item, quantity, location, price and date If name, barcode, item, location and price are the same - Update quantity and date (if more recent) 

Primero, agregue una restricción UNIQUE al nombre, código de barras, artículo, location y precio.

 ALTER TABLE tableX ADD CONSTRAINT tableX_UQ UNIQUE (name, barcode, item, location, price) ; 

Luego puede usar INSERT INTO ... ON DUPLICATE KEY UPDATE :

 INSERT INTO tableX (name, barcode, item, location, price, quantity, date) VALUES (?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE quantity = CASE WHEN VALUES(date) > date THEN quantity + VALUES(quantity) -- add quantity ELSE quantity -- or leave as it is END , date = CASE WHEN VALUES(date) > date THEN VALUES(date) ; -- set date to new date ELSE date -- or leave as it is END 

REPLACE también podría usarse, pero existen diferencias en el comportamiento (lo que es especialmente importante si tiene keys externas). Para get detalles, consulte la pregunta "INSERT IGNORE" frente a "INSERT … ON DUPLICATE KEY UPDATE" y la respuesta de @Bill Kawin que discute las diferencias entre INSERT IGNORE , INSERT ... ON DUPLICATE KEY y REPLACE .

Puede usar la syntax de reemploop en mysql.

Pero eso solo funcionaría con un índice único sobre … los campos que necesitan ser únicos.

Entonces, tendrías que crear un índice único como ese:

 alter <yourtable> add unique index(name, barcode, item, location, price); 

entonces su syntax de inserción / actualización se convertiría

 replace into <yourtable> (name, barcode, item, quantity, location, price, date) VALUES('name1', 'barcode1', 2, 'location1', 12.0, '25/12/2012'); 

EDITAR

Ejemplo de procedimiento almacenado (simplificado y no probado):

 DELIMITER && DROP PROCEDURE IF EXISTS MyBase.UpdateOrInsert $$ CREATE PROCEDURE MyBase.UpdateOrInsert ( IN _name VARCHAR(10), IN _barcode VARCHAR(50), IN _quantity INTEGER IN _date DATE ) DECLARE existingDate DATE default NULL; BEGIN SELECT date INTO existingDate FROM <yourTable> where name = _name and barcode = _barcode; if (existingDate IS NULL) then insert into <yourtable> (name, barcode, quantity, date) VALUES(_name, _barcode, _qantity, _date); else if (existingDate < _date) then update <yourtable> set quantity = _quantity, date = _date where name = _name and barcode = _barcode; end if; end if; END && 

Gracias a toda la ayuda de aquellos sobre la solución que encontré, al final estaba muy cerca de ambos. Encuéntrelo a continuación:

 INSERT INTO `stock` (name, barcode, item, quantity, location, price, date) VALUES (?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE quantity = CASE WHEN VALUES(date) < $date THEN quantity + $quantity ELSE quantity END, date = CASE WHEN VALUES(date) < $date THEN VALUES(date) ELSE $date END