Как получить идентификатор последней обновленной строки в MySQL с помощью PHP?
Я нашел ответ на эту проблему 🙂
SET @update_id := 0; UPDATE some_table SET column_name = 'value', id = (SELECT @update_id := id) WHERE some_other_column = 'blah' LIMIT 1; SELECT @update_id;
EDIT by aefxx
Этот метод может быть дополнительно расширен для получения идентификатора каждой строки, затронутой оператором обновления:
SET @uids := null; UPDATE footable SET foo = 'bar' WHERE fooid > 5 AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) ); SELECT @uids;
Это вернет строку со всеми идентификаторами, объединенными двоеточием.
Хм, я удивлен, что среди ответов я не вижу самого простого решения.
Предположим, item_id
является целым столбцом идентификатора в таблице items
и обновляет строки следующим выражением:
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd';
Затем, чтобы узнать последнюю затронутую строку сразу после утверждения, вы должны слегка обновить инструкцию следующим образом:
UPDATE items SET qwe = 'qwe', item_id=LAST_INSERT_ID(item_id) WHERE asd = 'asd'; SELECT LAST_INSERT_ID();
Если вам нужно обновить только измененную строку, вам нужно будет добавить условное обновление item_id через проверку LAST_INSERT_ID, если данные будут меняться в строке.
Это тот же метод, что и ответ Салмана А, но вот код, который вам действительно нужно сделать.
Сначала отредактируйте таблицу так, чтобы она автоматически отслеживала, когда изменяется строка. Удалите последнюю строку, если хотите узнать, когда была вставлена строка.
ALTER TABLE mytable ADD lastmodified TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Затем, чтобы узнать последнюю обновленную строку, вы можете использовать этот код.
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
Этот код отменяется из MySQL vs PostgreSQL: добавление столбца «Last Modified Time» в таблицу и руководство MySQL: Сортировка строк . Я только что собрал его.
Запрос:
$sqlQuery = "UPDATE update_table SET set_name = 'value' WHERE where_name = 'name' LIMIT 1;";
Функция PHP:
function updateAndGetId($sqlQuery) { mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery)); return mysql_insert_id(); }
Это для меня работа;)
Эй, мне просто нужен такой трюк – я решил это по-другому, может быть, это сработает для вас. Обратите внимание, что это не масштабируемое решение и будет очень плохо для больших наборов данных.
Разделите свой запрос на две части –
сначала выберите идентификаторы строк, которые вы хотите обновить, и сохраните их во временной таблице.
во-вторых, сделайте исходное обновление с условием в инструкции обновления, измененным на where id in temp_table
.
Чтобы обеспечить параллелизм, вам нужно заблокировать таблицу перед этими двумя шагами, а затем отпустить блокировку в конце.
Опять же, это работает для меня, для запроса, который заканчивается limit 1
, поэтому я даже не использую временную таблицу, а вместо этого просто переменную, чтобы сохранить результат первого select
.
Я предпочитаю этот метод, так как знаю, что всегда буду обновлять только одну строку, а код прост.
Идентификатор последней обновленной строки – это тот же идентификатор, который вы используете в «updateQuery», чтобы найти и обновить эту строку. Поэтому просто сохраните (вызовите) этот идентификатор в любом случае.
last_insert_id()
зависит от AUTO_INCREMENT
, но последний обновленный идентификатор отсутствует.
Это официально просто, но замечательно противоречит интуиции. Если вы делаете:
update users set status = 'processing' where status = 'pending' limit 1
Измените его так:
update users set status = 'processing' where status = 'pending' and last_insert_id(user_id) limit 1
Добавление last_insert_id(user_id)
в предложении where
говорит MySQL, чтобы установить свою внутреннюю переменную в идентификатор найденной строки. Когда вы передаете значение last_insert_id(expr)
подобное этому, оно заканчивает тем, что возвращает это значение, которое в случае идентификаторов, подобных здесь, всегда является положительным целым числом и поэтому всегда оценивает значение true, никогда не вмешиваясь в предложение where. Это работает только в том случае, если определенная строка действительно найдена, поэтому не забудьте проверить затронутые строки. Затем вы можете получить идентификатор несколькими способами.
MySQL last_insert_id()
Вы можете генерировать последовательности, не вызывая LAST_INSERT_ID (), но утилита использования этой функции заключается в том, что значение идентификатора поддерживается на сервере как последнее автоматически генерируемое значение. Он многопользовательский, поскольку несколько клиентов могут выдавать инструкцию UPDATE и получать собственное значение последовательности с помощью инструкции SELECT (или mysql_insert_id ()), не затрагивая или не подвергаясь воздействию других клиентов, которые генерируют свои собственные значения последовательности.
MySQL mysql_insert_id()
Возвращает значение, сгенерированное для столбца AUTO_INCREMENT предыдущим оператором INSERT или UPDATE. Используйте эту функцию после выполнения инструкции INSERT в таблице, содержащей поле AUTO_INCREMENT, или использовали INSERT или UPDATE для установки значения столбца с помощью LAST_INSERT_ID (expr).
Причина различий между LAST_INSERT_ID () и mysql_insert_id () заключается в том, что LAST_INSERT_ID () упрощается для использования в скриптах, а mysql_insert_id () пытается предоставить более точную информацию о том, что происходит с столбцом AUTO_INCREMENT.
PHP mysqli_insert_id()
Выполнение инструкции INSERT или UPDATE с использованием функции LAST_INSERT_ID () также изменит значение, возвращаемое функцией mysqli_insert_id ().
Объединяя все это:
$affected_rows = DB::getAffectedRows(" update users set status = 'processing' where status = 'pending' and last_insert_id(user_id) limit 1" ); if ($affected_rows) { $user_id = DB::getInsertId(); }
(FYI, что класс DB здесь ).
Если вы делаете только вставки и хотите один из одного сеанса, сделайте это в соответствии с ответом peirix. Если вы вносите изменения, вам нужно будет изменить схему базы данных, чтобы сохранить, какая запись была обновлена в последний раз.
Если вы хотите, чтобы идентификатор от последней модификации, возможно, был от другого сеанса (т. Е. Не тот, который был только что выполнен с помощью PHP-кода, работающего в настоящее время, но один из них был выполнен в ответ на другой запрос), вы можете добавить TIMESTAMP в таблицу с именем last_modified (см. http://dev.mysql.com/doc/refman/5.1/en/datetime.html для информации), а затем, когда вы обновляете, установите last_modified = CURRENT_TIME.
Установив это, вы можете использовать такой запрос, как: SELECT id FROM table ORDER BY last_modified DESC LIMIT 1; для получения последней измененной строки.
SET @uids := ""; UPDATE myf___ingtable SET id = id WHERE id < 5 AND ( SELECT @uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), @uids) ); SELECT @uids;
Мне пришлось CAST id (dunno why) … или я не могу получить контент @uids (это был blob). Большое спасибо за ответ Помыка!
Более подробно с вышеприведенным ответом
Для тех, кто задавался вопросом :=
& =
Значительная разница между :=
и =
, и это то, что :=
работает как оператор с переменным присваиванием всюду, а =
работает именно так в операторах SET и является оператором сравнения везде.
Таким образом SELECT @var = 1 + 1;
оставит @var
неизменным и возвращает логическое значение (1 или 0 в зависимости от текущего значения @var), тогда как SELECT @var := 1 + 1;
изменит @var
на 2 и вернет 2 . [Источник]
Мое решение: сначала выберите «id» (@uids) с помощью команды select и после обновления этого идентификатора с помощью @uids.
SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1); UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;
он работал над моим проектом.
Нет необходимости в столь длинном Mysql-коде. В PHP запрос должен выглядеть примерно так:
$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error'); $lastUpdatedId = mysql_insert_id();