Как получить идентификатор последней обновленной строки в MySQL с помощью PHP?
Как получить идентификатор последней обновленной строки в MySQL?
Ответ 1
Я нашел ответ на эту проблему :)
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;
РЕДАКТИРОВАТЬ aefxx
Этот метод может быть дополнительно расширен для получения идентификатора каждой строки, затронутой оператором обновления:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
Это вернет строку со всеми идентификаторами, соединенными запятой.
Ответ 2
Хм, меня удивляет, что среди ответов я не вижу самого простого решения.
Предположим, 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, проверяющего, будут ли данные изменяться в строке.
Ответ 3
Это тот же метод, что и ответ Salman A, но здесь код, который вам действительно нужно сделать.
Сначала отредактируйте свою таблицу так, чтобы она автоматически отслеживала, когда изменяется строка. Удалите последнюю строку, если вы хотите знать, когда была вставлена строка.
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: Сортировка строк. Я только что собрал его.
Ответ 4
Это официально просто, но удивительно нелогично. Если вы делаете:
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. Это работает, только если какая-то строка была фактически найдена, поэтому не забудьте проверить затронутые строки. Затем вы можете получить идентификатор несколькими способами.
Вы можете генерировать последовательности без вызова LAST_INSERT_ID(), но полезность использования этой функции заключается в том, что значение идентификатора сохраняется на сервере как последнее автоматически сгенерированное значение. Он безопасен для нескольких пользователей, поскольку несколько клиентов могут выполнить инструкцию UPDATE и получить свое собственное значение последовательности с помощью инструкции SELECT (или 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.
Выполнение оператора 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();
}
(К вашему сведению, класс БД находится здесь.)
Ответ 5
Запрос:
$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();
}
Это работает для меня;)
Ответ 6
Идентификатор последней обновленной строки - это тот же идентификатор, который вы используете в "updateQuery", чтобы найти и обновить эту строку. Итак, просто сохраните (вызовите) этот идентификатор в любом случае.
last_insert_id()
зависит от AUTO_INCREMENT
, но последний обновленный идентификатор отсутствует.
Ответ 7
Эй, мне просто нужен был такой трюк - я решил это по-другому, может быть, это сработает для вас. Обратите внимание, что это не масштабируемое решение и будет очень плохо для больших наборов данных.
Разделите запрос на две части -
сначала выберите идентификаторы строк, которые вы хотите обновить, и сохраните их во временной таблице.
во-вторых, сделайте исходное обновление с условием в операторе обновления, измененным на where id in temp_table
.
И для обеспечения concurrency вам нужно lock таблицу до этого двух шагов, а затем отпустить блокировку в конце.
Опять же, это работает для меня, для запроса, который заканчивается на limit 1
, поэтому я даже не использую временную таблицу, а вместо этого просто переменную для хранения результата первого select
.
Я предпочитаю этот метод, так как знаю, что всегда буду обновлять только одну строку, а код прост.
Ответ 8
В дополнение к вышеприведенному ответу
Для тех, кто задавался вопросом о :=
и =
Значительная разница между :=
и =
, и это то, что :=
работает как оператор с переменным присваиванием всюду, а =
работает именно так в операторах SET и является оператором сравнения везде.
Итак, SELECT @var = 1 + 1;
оставит @var
неизменным и вернет логическое (1 или 0 в зависимости от текущего значения @var), а SELECT @var := 1 + 1;
изменит @var
на 2 и return 2. [Источник]
Ответ 9
Если вы делаете только вставки и хотите один из того же сеанса, выполните в соответствии с ответом 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; для получения последней измененной строки.
Ответ 10
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) Btw большое спасибо за ответ Помыка!
Ответ 11
Мое решение - сначала решить "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;
он работал над моим проектом.
Ответ 12
Нет необходимости в таком длинном Mysql-коде. В PHP запрос должен выглядеть примерно так:
$updateQuery = mysql_query("UPDATE table_name SET row='value' WHERE id='$id'") or die ('Error');
$lastUpdatedId = mysql_insert_id();