MySQL ON DUPLICATE KEY UPDATE dla wielu wierszy wstaw w jednym zapytaniu

199

Mam zapytanie SQL, w którym chcę wstawić wiele wierszy w jednym zapytaniu. więc użyłem czegoś takiego:

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

mysql_query( $sql, $conn );

Problem polega na tym, że kiedy wykonuję to zapytanie, chcę sprawdzić, czy UNIQUEklucz (który nie jest PRIMARY KEY), np. 'name'Powyżej, powinien zostać sprawdzony, a jeśli taki 'name'już istnieje, odpowiedni cały wiersz powinien zostać zaktualizowany, w przeciwnym razie wstawiony.

Na przykład w poniższym przykładzie, jeśli 'Katrina'jest już obecny w bazie danych, cały wiersz, niezależnie od liczby pól, powinien zostać zaktualizowany. Ponownie, jeśli 'Samia'nie jest obecny, wiersz należy wstawić.

Myślałem o użyciu:

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

Oto pułapka. Utknąłem i byłem zdezorientowany, jak postępować. Mam wiele wierszy do wstawienia / aktualizacji na raz. Proszę o wskazówki. Dzięki.

Prashant
źródło

Odpowiedzi:

479

Użyj słowa kluczowego, VALUESaby odnieść się do nowych wartości (patrz dokumentacja ).

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
źródło
2
Co jeśli potrzebujemy dołączyć instrukcję JEŚLI do AKTUALIZACJI, która ma inny warunek dla każdego wiersza?
logika
2
@logic: Istnieje kilka pytań związanych z tym: Wyszukiwanie StackOverflow . Jeśli żaden z nich nie udzieli odpowiedzi na Twoje pytanie, opublikuj nowe, dokładnie wyjaśniając, czego potrzebujesz.
Peter Lang
@logic znalazłeś jakieś rozwiązanie swojego problemu? obecnie mam do czynienia z tym samym problemem
Parth kharecha
Świetna sugestia. Jeśli chcesz zwiększyć wartość podczas duplikowania, dodaj ją po części „NA DUPLIKATIE AKTUALIZACJI KLUCZA”: ogółem = suma + WARTOŚCI (suma)
Phoenix
1

INSERT INTO ... ON DUPLICATE KEY UPDATE będzie działać tylko dla MYSQL, a nie dla SQL Server.

w przypadku serwera SQL sposobem na obejście tego jest najpierw zadeklarowanie tabeli tymczasowej, wstawienie wartości do tej tabeli tymczasowej, a następnie użycie polecenia MERGE

Lubię to:

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
źródło
15
Kto jednak korzysta z serwera SQL: D
Jeremy Belolo,
-3

Możesz użyć Zastąp zamiast WSTAW ... NA DUPLIKACIE KLUCZOWEJ AKTUALIZACJI.

a1ex07
źródło
28
Tak, ale używając REPLACE stary wiersz jest usuwany przed wstawieniem nowego wiersza. Chcę zachować stary wiersz do obsługi podstawowych identyfikatorów.
Prashant
2
Nie zdawałem sobie sprawy, że zachowanie starego PK jest dla ciebie w jakiś sposób ważne ... Z pewnością REPLACE nie zadziała w tym przypadku ...
a1ex07
4
PS: „zamień na” wymaga zarówno uprawnień do usuwania, jak i wstawiania!
Oliver M. Grech,
2
a z wyżej wymienionych powodów usuwania / wstawiania jest również znacznie wolniejszy w tych przypadkach.
Ross
1
Co jeśli chcesz zaktualizować kilka kolumn? Zastąp zaktualizuje wszystkie.
imVJ