Mam następujące zapytanie:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
Chcę mieć identyfikator wkładki lub aktualizacji. Zwykle wykonuję drugie zapytanie, aby to uzyskać, ponieważ uważam, że insert_id () zwraca tylko 'wstawiony' identyfikator, a nie zaktualizowany identyfikator.
Czy istnieje sposób na WSTAWIENIE / AKTUALIZACJĘ i pobranie identyfikatora wiersza bez uruchamiania dwóch zapytań?
alter table tablename AUTO_INCREMENT = 0;
powyższe zapytanie, aby uniknąć dużych luk w wartościach identyfikatorów.Odpowiedzi:
Sprawdź tę stronę: https://web.archive.org/web/20150329004325/https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
U dołu strony wyjaśniają, w jaki sposób można nadać LAST_INSERT_ID znaczący dla aktualizacji, przekazując wyrażenie do tej funkcji MySQL.
Z przykładu dokumentacji MySQL:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
źródło
Dokładniej, jeśli jest to pierwotne zapytanie:
INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE a=1
a „id” jest kluczem podstawowym z automatyczną inkrementacją, niż byłoby to działające rozwiązanie:
INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), a=1
Wszystko jest tutaj: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
źródło
Możesz spojrzeć na REPLACE, które zasadniczo polega na usunięciu / wstawieniu, jeśli rekord istnieje. Ale to zmieniłoby pole automatycznego inkrementacji, jeśli jest obecne, co mogłoby spowodować zerwanie relacji z innymi danymi.
źródło
Nie wiem, jaka jest twoja wersja MySQL, ale w przypadku InnoDB wystąpił błąd z autoinc
błąd w 5.1.20 i poprawiony w 5.1.23 http://bugs.mysql.com/bug.php?id=27405
błąd w 5.1.31 i poprawiony w 5.1.33 http://bugs.mysql.com/bug.php?id=42714
źródło
Natknąłem się na problem, gdy NA DUPLICATE KEY UPDATE id = LAST_INSERT_ID (id) zwiększ klucz podstawowy o 1. Więc id następnego wejścia w sesji zostanie zwiększony o 2
źródło
Warto zauważyć, a to może być oczywiste (ale i tak powiem to dla jasności tutaj), że polecenie REPLACE spowoduje zdmuchnięcie istniejącego pasującego wiersza przed wstawieniem nowych danych. W PRZYPADKU DUPLICATE KEY UPDATE zaktualizuje tylko określone kolumny i zachowa wiersz.
Z instrukcji :
źródło
Istniejące rozwiązania działają, jeśli używasz autoinkrementacji. Mam sytuację, w której użytkownik może zdefiniować prefiks i powinien ponownie uruchomić sekwencję na 3000. Z powodu tego zróżnicowanego prefiksu nie mogę użyć funkcji autoincrement, co powoduje, że last_insert_id jest pusty dla wstawień. Rozwiązałem to następująco:
INSERT INTO seq_table (prefix, id) VALUES ('$user_prefix', LAST_INSERT_ID(3000)) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id + 1); SELECT LAST_INSERT_ID();
Jeśli prefiks istnieje, zwiększy go i zapełni last_insert_id. Jeśli przedrostek nie istnieje, wstawi przedrostek o wartości 3000 i wypełni last_insert_id wartością 3000.
źródło