MySQL ON DUPLICATE KEY UPDATE para inserção de múltiplas linhas em uma única consulta

199

Eu tenho uma consulta SQL onde desejo inserir várias linhas na consulta única. então eu usei algo como:

$sql = "INSERT INTO beautiful (name, age)
  VALUES
  ('Helen', 24),
  ('Katrina', 21),
  ('Samia', 22),
  ('Hui Ling', 25),
  ('Yumie', 29)";

mysql_query( $sql, $conn );

O problema é que, quando executo essa consulta, desejo verificar se uma UNIQUEchave (que não é a PRIMARY KEY), por exemplo 'name', acima, deve ser verificada e, se 'name'já existe, a linha inteira correspondente deve ser atualizada caso contrário.

Por exemplo, no exemplo abaixo, se 'Katrina'já estiver presente no banco de dados, a linha inteira, independentemente do número de campos, deve ser atualizada. Novamente, se 'Samia'não estiver presente, a linha deve ser inserida.

Eu pensei em usar:

INSERT INTO beautiful (name, age)
      VALUES
      ('Helen', 24),
      ('Katrina', 21),
      ('Samia', 22),
      ('Hui Ling', 25),
      ('Yumie', 29) ON DUPLICATE KEY UPDATE

Aqui está a armadilha. Fiquei preso e confuso sobre como proceder. Eu tenho várias linhas para inserir / atualizar de cada vez. Por favor me dê uma direção. Obrigado.

Prashant
fonte

Respostas:

479

Use a palavra VALUES- chave para se referir a novos valores (consulte a documentação ).

INSERT INTO beautiful (name, age)
    VALUES
    ('Helen', 24),
    ('Katrina', 21),
    ('Samia', 22),
    ('Hui Ling', 25),
    ('Yumie', 29)
ON DUPLICATE KEY UPDATE
    age = VALUES(age),
     ...
Peter Lang
fonte
2
E se precisarmos incluir uma instrução IF na UPDATE que tenha uma condição diferente para cada linha?
lógica
2
@logic: Existem várias perguntas relacionadas a isso: Pesquisa StackOverflow . Se nenhum deles responder à sua pergunta, publique uma nova explicando exatamente o que você precisa.
Peter Lang
@logic você encontrou alguma solução para o seu problema? atualmente estou enfrentando o mesmo problema
Parth kharecha 03/04
Ótima sugestão. Se você deseja incrementar um valor quando duplicado, adicione-o após a parte "ON DUPLICATE KEY UPDATE": total = total + VALORES (total)
phoenix em
1

INSERT INTO ... ON DUPLICATE KEY UPDATE funcionará apenas para MYSQL, não para SQL Server.

para SQL Server, a maneira de contornar isso é primeiro declarar uma tabela temporária, inserir valor nessa tabela temporária e usar MERGE

Como isso:

declare @Source table
(
name varchar(30),
age decimal(23,0)
)

insert into @Source VALUES
('Helen', 24),
('Katrina', 21),
('Samia', 22),
('Hui Ling', 25),
('Yumie', 29);


MERGE beautiful  AS Tg
using  @source as Sc
on tg.namet=sc.name 

when matched then update 
set tg.age=sc.age

when not matched then 
insert (name, age) VALUES
(SC.name, sc.age);
li rachel
fonte
15
Quem usa o servidor SQL que: D
Jeremy Belolo
-3

Você pode usar Substituir em vez de INSERIR ... NA DUPLICATE KEY UPDATE.

a1ex07
fonte
28
Sim, mas usando REPLACE, a linha antiga é excluída antes da inserção da nova linha. Quero manter a linha antiga para manter os IDs principais.
Prashant
2
Eu não tinha percebido que a manutenção do velho PK é de alguma forma importante para você ... Certamente, REPLACE não funcionará neste caso ...
a1ex07
4
PS: "substituir em" requer privilégios de exclusão e inserção!
Oliver M Grech 13/09
2
e pelos motivos de exclusão / inserção acima mencionados, também é muito mais lento nesses casos.
Ross Ross
1
E se você quiser atualizar algumas colunas? Substituir atualizará tudo.
imVJ