MySQL ON DUPLICATE KEY - последний идентификатор вставки?
У меня есть следующий запрос:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
Мне нужен идентификатор вставки или обновления. Обычно я запускаю второй запрос, чтобы получить это, поскольку я считаю, что insert_id() возвращает только "вставленный" идентификатор, а не обновленный идентификатор.
Есть ли способ INSERT/UPDATE и получить идентификатор строки без запуска двух запросов?
Ответы
Ответ 1
Проверьте эту страницу: https://web.archive.org/web/20150329004325/https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Внизу страницы они объясняют, как вы можете сделать LAST_INSERT_ID значимым для обновлений, передавая выражение в эту функцию MySQL.
Из примера документации MySQL:
Если таблица содержит столбец AUTO_INCREMENT и INSERT... UPDATE вставляет строку, функция LAST_INSERT_ID() возвращает значение AUTO_INCREMENT. Если инструкция обновляет строку, LAST_INSERT_ID() не имеет смысла. Однако вы можете обойти это, используя LAST_INSERT_ID (expr). Предположим, что id является столбцом AUTO_INCREMENT. Чтобы сделать LAST_INSERT_ID() значимым для обновлений, вставьте строки следующим образом:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
Ответ 2
Чтобы быть точным, если это исходный запрос:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
и 'id' - это первичный ключ с автоматическим приращением, чем это было бы рабочим решением:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), a=1
Здесь все: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Если таблица содержит столбец AUTO_INCREMENT и INSERT... UPDATE вставляет строку, функция LAST_INSERT_ID() возвращает Значение AUTO_INCREMENT. Если инструкция обновляет строку, LAST_INSERT_ID() не имеет смысла. Однако вы можете обойти это используя LAST_INSERT_ID (expr). Предположим, что id является AUTO_INCREMENT столбец.
Ответ 3
Вы можете посмотреть REPLACE, который по существу является удалением/вставкой, если запись существует. Но это изменит поле автоматического приращения, если оно присутствует, что может сломать отношения с другими данными.
Ответ 4
Я не знаю, какая у вас версия MySQL, но с InnoDB, была ошибка с autoinc
ошибка в 5.1.20 и исправлена в 5.1.23
http://bugs.mysql.com/bug.php?id=27405
в 5.1.31 и исправлена в 5.1.33
http://bugs.mysql.com/bug.php?id=42714
Ответ 5
Стоит отметить, и это может быть очевидно (но я все равно скажу это для ясности), что REPLACE сдует существующую совпадающую строку перед вставкой ваших новых данных. ON DUPLICATE KEY UPDATE обновит только указанные столбцы и сохранит строку.
Из руководство:
REPLACE работает точно так же, как INSERT, за исключением того, что если старая строка в таблице имеет такое же значение, как новая строка для PRIMARY KEY или UNIQUE индекс, старый строка удаляется до того, как новая строка будет вставлены.
Ответ 6
Существующие решения работают, если вы используете автоинкремент. У меня есть ситуация, когда пользователь может определить префикс, и он должен перезапустить последовательность на 3000. Из-за этого разнообразного префикса я не могу использовать автоинкремент, который делает last_insert_id пустым для вставок. Я решил это со следующим:
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();
Если префикс существует, он будет увеличивать его и заполнять last_insert_id.
Если префикс не существует, он вставляет префикс со значением 3000 и заполняет last_insert_id 3000.