如何使用PHP获取MySQL中最后更新的行的ID?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
如何使用PHP获取MySQL中最后更新的行的ID?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?
Answers:
我找到了这个问题的答案:)
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 编辑
可以进一步扩展此技术以检索受更新语句影响的每一行的ID:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
这将返回一个字符串,其中所有ID均由逗号连接。
WHERE
子句,您可以WHERE
在下一个查询中使用相同的子句SELECT id FROM footable WHERE fooid > 5
LAST_INSERT_ID()
可以接受一个参数,该参数将设置下次调用时返回的值LAST_INSERT_ID()
。例如:UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';
。现在,SELECT LAST_INSERT_ID();
将返回更新的ID。有关更多详细信息,请参见newtover的答案。
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);
。但是,它不会检索多个ID,因此此答案更好。
嗯,令我惊讶的是,在答案中我没有看到最简单的解决方案。
假设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();
如果您只需要更新真正更改的行,则需要通过LAST_INSERT_ID添加对item_id的条件更新,以检查行中的数据是否要更改。
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
官方上这很简单,但明显违反直觉。如果您正在做:
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来设置它的内部变量为所找到的行的ID。当您传递一个last_insert_id(expr)
类似的值时,它最终会返回该值,对于像此处这样的ID来说,它始终是一个正整数,因此始终求值为true,而不会干扰where子句。这仅在实际找到某行的情况下才有效,因此请记住检查受影响的行。然后,您可以通过多种方式获取ID。
您可以生成序列而无需调用LAST_INSERT_ID(),但是以这种方式使用该函数的实用工具是将ID值作为最后一个自动生成的值保留在服务器中。这是多用户安全的,因为多个客户端可以发出UPDATE语句并使用SELECT语句(或mysql_insert_id())获得自己的序列值,而不会影响或受到生成自己序列值的其他客户端的影响。
返回由先前的INSERT或UPDATE语句为AUTO_INCREMENT列生成的值。对包含AUTO_INCREMENT字段的表执行INSERT语句,或者使用INSERT或UPDATE设置带有LAST_INSERT_ID(expr)的列值后,请使用此功能。
LAST_INSERT_ID()和mysql_insert_id()之间存在差异的原因是,使得LAST_INSERT_ID()易于在脚本中使用,而mysql_insert_id()试图提供有关AUTO_INCREMENT列发生了什么的更准确的信息。
使用LAST_INSERT_ID()函数执行INSERT或UPDATE语句还将修改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();
}
(仅供参考,DB类在这里。)
这与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相对于PostgreSQL删除的:在表和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();
}
这对我有用;)
我的解决方案是,首先使用select命令确定“ id”(@ uids),然后使用@uids更新此id。
SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;
它对我的项目有效。
如果您只进行插入操作,并且希望在同一会话中进行插入操作,请按照peirix的回答进行操作。如果要进行修改,则需要修改数据库架构以存储最近更新的条目。
如果您想要上次修改的ID(可能是来自其他会话的ID)(即不是当前运行的PHP代码刚刚完成的ID,而是为了响应不同的请求而完成的ID),则可以添加一个表的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; 获取最新修改的行。