Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como INSERT se a linha não existir (UPSERT) no MySQL

  • Usando INSERT IGNORE
  • Usando REPLACE
  • Usando INSERT ... ON DUPLICATE KEY UPDATE

O MySQL fornece várias instruções úteis quando é necessário INSERT linhas depois determinar se essa linha é, de fato, nova ou já existe.

Abaixo, examinaremos os três métodos diferentes e explicaremos os prós e contras de cada um, para que você tenha uma compreensão firme de como configurar suas próprias instruções ao fornecer dados novos ou potencialmente existentes para INSERTION .

Usando INSERT IGNORE


Usando INSERT IGNORE efetivamente faz com que o MySQL ignore erros de execução ao tentar executar INSERT declarações. Isso significa que um INSERT IGNORE instrução que contém um valor duplicado em um UNIQUE index ou PRIMARY KEY campo não produzirá um erro, mas simplesmente ignorará esse INSERT específico comanda inteiramente. O propósito óbvio é executar um grande número de INSERT instruções para uma combinação de dados que já existem no banco de dados, bem como novos dados que chegam ao sistema.

Por exemplo, nossos books table já pode conter alguns registros:
mysql> SELECT * FROM books LIMIT 3;
+----+-------------------------+---------------------+----------------+
| id | title                   | author              | year_published |
+----+-------------------------+---------------------+----------------+
|  1 | In Search of Lost Time  | Marcel Proust       |           1913 |
|  2 | Ulysses                 | James Joyce         |           1922 |
|  3 | Don Quixote             | Miguel de Cervantes |           1605 |
+----+-------------------------+---------------------+----------------+
3 rows in set (0.00 sec)

Se tivermos um grande lote de dados novos e existentes para INSERT e parte desses dados contém um valor correspondente para o id campo (que é um campo UNIQUE PRIMARY_KEY na tabela), usando um INSERT básico produzirá um erro esperado:
mysql> INSERT INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

Por outro lado, se usarmos INSERT IGNORE , a tentativa de duplicação é ignorada e nenhum erro resultante ocorre:
mysql> INSERT IGNORE INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 0 rows affected (0.00 sec)

Usando REPLACE


Caso você deseje realmente substituir linhas onde INSERT comandos produziriam erros devido a duplicação de UNIQUE ou PRIMARY KEY valores conforme descrito acima, uma opção é optar pelo REPLACE demonstração.

Ao emitir um REPLACE instrução, há dois resultados possíveis para cada comando emitido:
  • Nenhuma linha de dados existente foi encontrada com valores correspondentes e, portanto, um padrão INSERT instrução é executada.
  • Uma linha de dados correspondente é encontrado, fazendo com que a linha existente seja excluída com o padrão DELETE instrução, então um INSERT normal é realizado depois.

Por exemplo, podemos usar REPLACE para trocar nosso registro existente de id = 1 de Em busca do tempo perdido por Marcel Proust com Ovos Verdes e Presunto por Dr. Seuss:
mysql> REPLACE INTO books
    (id, title, author, year_published)
VALUES
    (1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
Query OK, 2 rows affected (0.00 sec)

Observe que, embora tenhamos alterado apenas uma linha, o resultado indica que duas linhas foram afetadas porque na verdade DELETED a linha existente então INSERTED a nova linha para substituí-la.

Mais informações sobre como usar REPLACE pode ser encontrada na documentação oficial.

Usando INSERT ... ON DUPLICATE KEY UPDATE


O método alternativo (e geralmente preferido) para INSERTING em linhas que podem conter UNIQUE duplicado ou PRIMARY KEY valores é usar o INSERT ... ON DUPLICATE KEY UPDATE declaração e cláusula.

Ao contrário de REPLACE – um comando inerentemente destrutivo devido ao DELETE comandos que ele executa quando necessário – usando INSERT ... ON DUPLICATE KEY UPDATE é não destrutivo , pois só emitirá INSERT ou UPDATE instruções, mas nunca DELETE .

Por exemplo, decidimos que desejamos substituir nosso id = 1 registro de Ovos Verdes e Presunto e reverter para o original Em busca do tempo perdido gravar em vez disso. Podemos, portanto, usar nosso INSERT original e adicione o novo ON DUPLICATE KEY UPDATE cláusula:
mysql> SET @id = 1,
    @title = 'In Search of Lost Time',
    @author = 'Marcel Proust',
    @year_published = 1913;
INSERT INTO books
    (id, title, author, year_published)
VALUES
    (@id, @title, @author, @year_published)
ON DUPLICATE KEY UPDATE
    title = @title,
    author = @author,
    year_published = @year_published;

Observe que estamos usando o UPDATE normal sintaxe (mas excluindo a table desnecessária nome e SET palavra-chave), e apenas atribuindo o non-UNIQUE valores. Além disso, embora desnecessário para o ON DUPLICATE KEY UPDATE para funcionar corretamente, também optamos por utilizar user variables então não precisamos especificar os valores reais que queremos INSERT ou UPDATE mais de uma vez.

Como resultado, nosso id = 1 registro foi corretamente UPDATED como esperado:
mysql> SELECT * FROM books LIMIT 1;
+----+------------------------+---------------+----------------+
| id | title                  | author        | year_published |
+----+------------------------+---------------+----------------+
|  1 | In Search of Lost Time | Marcel Proust |           1913 |
+----+------------------------+---------------+----------------+
1 row in set (0.00 sec)

Mais informações podem ser encontradas na documentação oficial.