este problema se puede solucionar de variadas formas, pero te dejamos la que para nosotros es la resolución más completa.
Solución:
usar INSERT IGNORE INTO table
ver http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html
también hay INSERT … ON DUPLICATE KEY UPDATE
sintaxis, puede encontrar explicaciones en dev.mysql.com
Publica desde bogdan.org.ua según el caché web de Google:
18 de octubre de 2007
Para empezar: a partir de la última versión de MySQL, la sintaxis presentada en el título no es posible. Pero hay varias formas muy sencillas de lograr lo que se espera utilizando la funcionalidad existente.
Hay 3 posibles soluciones: usar INSERT IGNORE, REPLACE o INSERT … ON DUPLICATE KEY UPDATE.
Imagina que tenemos una mesa:
CREATE TABLE `transcripts` ( `ensembl_transcript_id` varchar(20) NOT NULL, `transcript_chrom_start` int(10) unsigned NOT NULL, `transcript_chrom_end` int(10) unsigned NOT NULL, PRIMARY KEY (`ensembl_transcript_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Ahora imagine que tenemos una canalización automática que importa metadatos de transcripciones de Ensembl, y que debido a varias razones, la canalización podría romperse en cualquier paso de la ejecución. Por lo tanto, debemos asegurarnos de dos cosas:
las ejecuciones repetidas de la tubería no destruirán nuestra base de datos
ejecuciones repetidas no morirán debido a ‘duplicados primarios key’errores.
Método 1: usar REPLACE
Es muy simple:
REPLACE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
Si el registro existe, se sobrescribirá; si aún no existe, se creará. Sin embargo, usar este método no es eficiente para nuestro caso: no necesitamos sobrescribir los registros existentes, está bien simplemente omitirlos.
Método 2: usar INSERT IGNORE También es muy simple:
INSERT IGNORE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
Aquí, si el ‘ensembl_transcript_id’ ya está presente en la base de datos, se omitirá en silencio (se ignorará). (Para ser más precisos, aquí hay una cita del manual de referencia de MySQL: “Si usa la palabra clave IGNORE, los errores que ocurren al ejecutar la instrucción INSERT se tratan como advertencias. Por ejemplo, sin IGNORE, una fila que duplica un índice UNIQUE existente o PRIMARY KEY valor en la tabla causa un duplicado-key error y la declaración se cancela ”.) Si el registro aún no existe, se creará.
Este segundo método tiene varias debilidades potenciales, incluida la no cancelación de la consulta en caso de que ocurra cualquier otro problema (ver el manual). Por lo tanto, debe usarse si se probó previamente sin la palabra clave IGNORE.
Método 3: usar INSERT … ON DUPLICATE KEY UPDATE:
La tercera opción es usar
INSERT … ON DUPLICATE KEY UPDATE
sintaxis, y en la parte ACTUALIZAR simplemente no hacer nada, hacer alguna operación sin sentido (vacía), como calcular 0 + 0 (Geoffray sugiere hacer la asignación id = id para que el motor de optimización MySQL ignore esta operación). La ventaja de este método es que solo ignora los duplicados
key eventos, y aún aborta en otros errores.Como último aviso: esta publicación se inspiró en Xaprb. También aconsejaría consultar su otra publicación sobre cómo escribir consultas SQL flexibles.
Solución:
INSERT INTO `table` (`value1`, `value2`)
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1)
Explicación:
La consulta más interna
SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1
utilizado como el WHERE NOT EXISTS
-condición detecta si ya existe una fila con los datos a insertar. Una vez que se encuentra una fila de este tipo, la consulta puede detenerse, por lo que LIMIT 1
(microoptimización, puede omitirse).
La consulta intermedia
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
representa los valores a insertar. DUAL
se refiere a una tabla especial de una fila y una columna presente de forma predeterminada en todas las bases de datos de Oracle (consulte https://en.wikipedia.org/wiki/DUAL_table). En una versión 5.7.26 de MySQL-Server, obtuve una consulta válida al omitir FROM DUAL
, pero las versiones anteriores (como 5.5.60) parecen requerir el FROM
información. Mediante el uso WHERE NOT EXISTS
la consulta intermedia devuelve un conjunto de resultados vacío si la consulta más interna encontró datos coincidentes.
La consulta externa
INSERT INTO `table` (`value1`, `value2`)
inserta los datos, si la consulta intermedia devuelve alguno.
en duplicado key actualizar o insertar ignorar pueden ser soluciones viables con MySQL.
Ejemplo de duplicado key actualización actualización basada en mysql.com
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;
Ejemplo de insertar ignorar basado en mysql.com
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUE (expr ,...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
O:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name= DEFAULT, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
O:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
Sección de Reseñas y Valoraciones
Tienes la opción de animar nuestro cometido exponiendo un comentario o valorándolo te damos las gracias.