如何获取PHP中MySQL表的最后插入的ID?


93

我有一个经常插入新数据的表。我需要获取表的最后一个ID。我怎样才能做到这一点?

类似于SELECT MAX(id) FROM table吗?


1
是的,您此查询将返回表的最后一个ID。但是一个条件是ID必须是主键。这样就可以避免re悔。
sathish

7
@sathish:该方法的主要问题是并发性
CMS

3
详细说明:问题在于,如果其他人在INSERT和查询之间的表中插入了某些内容MAX(id),则您可能会得到一个不是您的最后一个ID的ID。
deceze

3
@Jocelyn该问题在一年后被问到,其观看次数比该问题少数千次。
Naftali又名Neal

3
@尼尔,你是对的。另一个问题应作为该问题的副本予以解决。
Jocelyn

Answers:


133

如果您使用的是PDO,请使用PDO::lastInsertId

如果您使用的是Mysqli,请使用mysqli::$insert_id

如果您仍在使用Mysql:

请不要mysql_*在新代码中使用函数。它们已不再维护,已正式弃用。看到红色框了吗?了解准备的语句来代替,并使用 PDO库MySQLi -本文将帮助你决定哪些。如果您选择PDO,这是一个很好的教程

但是,如果需要,请使用mysql_insert_id


这个问题是如果您发生了很多插入操作(例如您的数据库也记录了某些内容),则可能会得到错误的ID。
迈克

@Mike如果你不使用mysql_insert_id 之后你的mysql_query。当然,如果您在两者之间的同一连接上执行其他几个查询,那没有什么可以帮助您的。
降低

7
为了确保您永远都不会得到错误的ID,请使用TRANSACTION包装代码。
Marcelo Assis 2012年

28
mysql确保这是当前连接的最后一个id,因此,如果在插入查询后紧紧放置此语句,就不会有问题。无需担心其他进程执行插入操作,也无需将其包装在事务中。mysql手册说:“所生成的ID在服务器中基于每个连接进行维护。这意味着该函数返回给定客户端的值是为影响AUTO_INCREMENT列的最新语句生成的第一个AUTO_INCREMENT值通过该客户端,这是你应该的理由使用选择MAX(ID)
woens

1
@deceze,PDO我们到处都看到这种偏见是什么?让我们再次看一下功能比较。很明显,mysqli当您需要用低水平的东西弄脏手时,这就是赢家。换句话说,即使选择PDO,他最终仍将需要使用mysqli
Pacerier,2015年

53

有一个函数可以知道当前连接中插入的最后一个ID是什么

mysql_query('INSERT INTO FOO(a) VALUES(\'b\')');
$id = mysql_insert_id();

加上使用max是个坏主意,因为如果在两个不同的会话中同时使用您的代码,可能会导致问题

该函数称为mysql_insert_id


2
mysql _(...)在PHP> = 5.5版本中已弃用。
Iago

是的,我只是想起那件事。:)
Iago 2014年



8

id假设它们是独特的并且自动递增的,那么您所写的内容将为您带来最大的收益,假设您可以处理并发问题,那么这很好。
由于您使用MySQL作为数据库,因此有一个特定功能LAST_INSERT_ID()仅在执行插入操作的当前连接上有效。
PHP为此提供了一个特定的功能mysql_insert_id


6

试试这个应该工作正常:

$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$query = "INSERT blah blah blah...";
$result = mysqli_query($link, $query);

echo mysqli_insert_id($link);

1
感谢您的关注。我已经编辑了代码,实际上是$ link(保持连接的变量)
Sandhu

3

您可以通过内置的php函数获取最新插入的ID mysql_insert_id();

$id = mysql_insert_id();

您还可以通过获得最新的ID

$id = last_insert_id();

4
另外,这是错误的,因为它建议使用不建议使用的库。真的,删除此
STT LCU

@STTLCU这里不推荐使用哪个代码段?
TheBlackBenzKid 2014年

@TheBlackBenzKid都是,因为它们都基于mysql_ *函数
STT LCU

@Rahul $ id = last_insert_id(); 不起作用,可能已过时。
Esha 2014年

3

要在codeigniter中获取最后插入的id,在执行插入查询后,只需使用一个名为 insert_id()数据库上,它将返回最后插入的ID

例如:

$this->db->insert('mytable',$data);
echo $this->db->insert_id(); //returns last inserted id

一行

echo $this->db->insert('mytable',$data)->insert_id();


2

干净简单-

$selectquery="SELECT id FROM tableName ORDER BY id DESC LIMIT 1";
$result = $mysqli->query($selectquery);
$row = $result->fetch_assoc();
echo $row['id'];

1

注意:如果用一条语句执行多次插入,mysqli :: insert_id将不正确。

桌子:

create table xyz (id int(11) auto_increment, name varchar(255), primary key(id));

现在,如果您这样做:

insert into xyz (name) values('one'),('two'),('three');

mysqli :: insert_id将为1而不是3。

要获取正确的值,请执行以下操作:

mysqli::insert_id + mysqli::affected_rows) - 1

这是文档,但有点晦涩。


1

我更喜欢使用纯MySQL语法来获取我想要的表的最后一个auto_increment id。

php mysql_insert_id()和mysql last_insert_id()仅给出最后的事务ID。

如果您想要模式中任何表的最后一个auto_incremented ID(不仅是最后一个事务),可以使用此查询

SELECT AUTO_INCREMENT FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'my_database' 
    AND TABLE_NAME = 'my_table_name';

而已。


我对此表示怀疑,因为在问题的上下文中此SQL完全是错误的...。当两个或多个客户端同时执行此SQL时,此方法也容易出现竞争情况...我不确定插入后此列数据的更新速度有多快,这使我怀疑。可以获取最后一个ID的PHP函数基于连接/会话级别(与MySQL的LAST_INSERT_ID()大致相同),从而节省了竞争条件
Raymond Nijland

1

遗憾的是没有看到一个示例的答案。

使用Mysqli :: $ insert_id

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$mysqli->query($sql);
$last_inserted_id=$mysqli->insert_id; // returns last ID

使用PDO :: lastInsertId

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$database->query($sql);
$last_inserted_id=$database->lastInsertId(); // returns last ID

0

使用MySQLi事务有时我无法获取mysqli::$insert_id,因为它返回0。特别是如果我使用存储过程,则执行INSERTs。因此,事务内还有另一种方式:

<?php

function getInsertId(mysqli &$instance, $enforceQuery = false){
    if(!$enforceQuery)return $instance->insert_id;

    $result = $instance->query('SELECT LAST_INSERT_ID();');

    if($instance->errno)return false;

    list($buffer) = $result->fetch_row();

    $result->free();

    unset($result);

    return $buffer;
}

?>

0

使用mysqli作为mysql的描述

<?php
$mysqli = new mysqli("localhost", "yourUsername", "yourPassword", "yourDB");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
// Conside employee table with id,name,designation
$query = "INSERT INTO myCity VALUES (NULL, 'Ram', 'Developer')";
$mysqli->query($query);

printf ("New Record has id %d.\n", $mysqli->insert_id);

/* close connection */
$mysqli->close();
?>

0

我试过了

mysqli_insert_id($ dbConnectionObj)

这将返回当前连接的最后插入的ID,因此,如果您正确管理连接,这应该可以工作。至少为我工作。


0

请使用PDP,然后尝试

$stmt = $db->prepare("...");
$stmt->execute();
$id = $db->lastInsertId();


-1

通过所有这些讨论,我假设检查最大ID的原因是要知道下一个ID是什么(如果我的最大ID是5,则下一个将是5 + 1 = 6)。

>>如果不是这个原因,我最好的歉意

如果其他人在您的CHECK和INSERT之间插入信息会给您错误的ID。

因此,可以解决是否创建包含时间戳或其他唯一值的哈希。

然后,在同一函数中,您可以使用空值和哈希值插入信息。如果您选择了AUTO_INCRECEMENT,则将创建ID。

然后,在相同的函数中,您仍将具有哈希,并且可以使用相同的哈希查找id。然后,您可以使用mysql UPDATE完成填充空值。

这包括更多的连接,但这仍然是一种方法。

祝你好运解决它。


-2

如果您的表具有AUTO INCREMENT列(如UserID,Emp_ID等),则可以使用此查询获取最后插入的记录 SELECT * FROM table_name,其中UserID =(从table_name选择MAX(UserID)) 在PHP代码中:

$con = mysqli_connect('localhost', 'userid', 'password', 'database_name');
                                if (!$con) {
                                    die('Could not connect: ' . mysqli_error($con));
                                }
                                $sql = "SELECT * FROM table_name where UserID=(select MAX(UserID)from table_name)";
                                $result = mysqli_query($con, $sql);

然后,您可以使用提取的数据作为需求


不要加密密码,当攻击者获得数据库时,他还将获得加密密钥。
zaph

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.