Saltar al contenido

¿Cómo ‘insertar si no existe’ en MySQL?

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:

  1. las ejecuciones repetidas de la tubería no destruirán nuestra base de datos

  2. 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *