Wstaw tabelę MySql, jeśli nie istnieje, w przeciwnym razie zaktualizuj

105
UPDATE AggregatedData SET datenum="734152.979166667", 
Timestamp="2010-01-14 23:30:00.000" WHERE datenum="734152.979166667";

Działa, jeśli datenumistnieje, ale chcę wstawić te dane jako nowy wiersz, jeśli datenumnie istnieje.

AKTUALIZACJA

datenum jest unikalne, ale nie jest to klucz podstawowy

O LA LA
źródło
2
Czy „datenum” jest unikalne? Możesz użyć INSERT ... ON DUPLICATE KEY UPDATE, jeśli tak jest.
Jacob

Odpowiedzi:

143

Jai ma rację, której powinieneś używać INSERT ... ON DUPLICATE KEY UPDATE.

Zwróć uwagę, że nie musisz uwzględniać danych w klauzuli update, ponieważ jest to unikalny klucz, więc nie powinien się zmieniać. Musisz uwzględnić wszystkie inne kolumny z tabeli. Możesz użyć tej VALUES()funkcji, aby upewnić się, że podczas aktualizowania innych kolumn są używane prawidłowe wartości.

Oto Twoja aktualizacja napisana ponownie przy użyciu poprawnej INSERT ... ON DUPLICATE KEY UPDATEskładni MySQL:

INSERT INTO AggregatedData (datenum,Timestamp)
VALUES ("734152.979166667","2010-01-14 23:30:00.000")
ON DUPLICATE KEY UPDATE 
  Timestamp=VALUES(Timestamp)
Ike Walker
źródło
18
Zachowaj ostrożność podczas używania INSERT ... ON DUPLICATE KEY UPDATE w tabelach z tabelą mającą więcej niż jeden klucz unikalny lub podstawowy. Zaczerpnięte z dokumentacji MySQL : Ponadto, począwszy od MySQL 5.5.24, instrukcja INSERT ... ON DUPLICATE KEY UPDATE w odniesieniu do tabeli mającej więcej niż jeden klucz unikalny lub podstawowy jest również oznaczana jako niebezpieczna. (Bug # 11765650, Bug # 58637) Błąd 58637 opis bugs.mysql.com/bug.php?id=58637
szerokopasmowy
1
Może być konieczne utworzenie UNIQUEograniczenia za TimestamppomocąALTER TABLE AggregatedData ADD UNIQUE (Timestamp)
Avyakt
@broadband możesz użyć klucza złożonego, aby uniknąć tego błędu
Kareem
16

Spróbuj użyć tego :

Jeśli określisz ON DUPLICATE KEY UPDATE, i zostanie wstawiony wiersz, który spowodowałby zduplikowaną wartość w UNIQUE index orPRIMARY KEY , MySQL performs an [UPDATE`] ( http://dev.mysql.com/doc/refman/5.7/en/update.html ) starego wiersza. ..

ON DUPLICATE KEY UPDATEPunkt może zawierać wiele zadań kolumn, oddzielony przecinkami.

W ON DUPLICATE KEY UPDATEprzypadku wartości wierszy, których to dotyczy, na wiersz wynosi 1, jeśli wiersz zostanie wstawiony jako nowy wiersz, 2, jeśli istniejący wiersz zostanie zaktualizowany, i 0, jeśli istniejący wiersz jest ustawiony na bieżące wartości. Jeśli określisz CLIENT_FOUND_ROWSflagę do mysql_real_connect()podczas łączenia się z mysqld , zmienna wartość wierszy będzie wynosić 1 (nie 0), jeśli istniejący wiersz jest ustawiony na bieżące wartości ...

Jai
źródło
Ale moja data nie jest kluczem podstawowym.
OHLÁLÁ
Więc w moim przypadku jakie jest rozwiązanie, wypróbowałem to bez żadnego rozwiązania: INSERT INTO forwind.aggregateddata (datenum, Timestamp, Min_F1_baro_20_) VALUES ('1', '2', '3') ON DUPLICATE KEY UPDATE datenum = datenum;
OHLÁLÁ
1
czy datenum ma być unikalne? jeśli tak, to dodaj do niego unikalny indeks (jeśli jeszcze nie został dodany) Wtedy to zadziała. Odwiedź stronę dev.mysql.com/doc/refman/5.1/en/alter-table.html, aby dowiedzieć się, jak reklamować UNIKALNE indeksy
Jai
teraz zdefiniowałem datę jako unikalną i działa dobrze, dzięki
OHLÁLÁ
1
Tylko link, może podaj odpowiedź.
Andrew
0

Miałem sytuację, w której musiałem zaktualizować lub wstawić do tabeli zgodnie z dwoma polami (oba klucze obce), na których nie mogłem ustawić UNIQUE ograniczenia (więc INSERT ... ON DUPLICATE KEY UPDATE nie zadziała). Oto, czego ostatecznie użyłem:

replace into last_recogs (id, hasher_id, hash_id, last_recog) 
  select l.* from 
    (select id, hasher_id, hash_id, [new_value] from last_recogs 
     where hasher_id in (select id from hashers where name=[hasher_name])
     and hash_id in (select id from hashes where name=[hash_name]) 
     union 
     select 0, m.id, h.id, [new_value] 
     from hashers m cross join hashes h 
     where m.name=[hasher_name] 
     and h.name=[hash_name]) l 
  limit 1;

Ten przykład pochodzi z jednej z moich baz danych, a parametry wejściowe (dwie nazwy i liczba) zostały zastąpione przez [hasher_name], [hash_name] i [new_value]. Zagnieżdżony SELECT ... LIMIT 1 pobiera pierwszy z istniejącego rekordu lub nowy rekord (last_recogs.id jest kluczem podstawowym z funkcją autoinkrementacji) i używa go jako wartości wejściowej do REPLACE INTO.

salfter
źródło
REPLACE zawsze wstawia nowy wiersz! po prostu usuwa oryginalny, już istniejący!
jasie