Skip to content

MySQL 获取最后插入 ID

当您向具有 AUTO_INCREMENT 主键列的数据库表中插入新行时,获取为该新行自动生成的 ID 通常很有用。然后可以将此 ID 用于后续操作,例如将相关数据插入其他表。

考虑带有 AUTO_INCREMENT 主键 id 的 MyGuests 表:

CREATE TABLE MyGuests (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

mysqli 和 PDO 扩展都提供了获取当前数据库连接最后插入 ID 的方法。

重要提示:您必须在同一个连接上成功执行 INSERT 查询后立即调用该方法。

此示例演示了如何连接、使用预处理语句(最佳实践!)插入数据,以及如何检索最后插入的 ID。

<?php
// 最佳实践:安全地存储凭据,不要直接写在代码中。
// 考虑使用环境变量或配置文件。
$servername = "localhost";
$username = "your_username"; // 替换为您的数据库用户名
$password = "your_password"; // 替换为您的数据库密码
$dbname = "myDB"; // 替换为您的数据库名
// 创建连接
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 启用错误异常
$conn = new mysqli($servername, $username, $password, $dbname);
// 设置字符集(推荐)
$conn->set_charset('utf8mb4');
$firstname = 'Peter';
$lastname = 'Jones';
$email = 'peter.jones@example.com';
try {
// 准备预处理语句(防止 SQL 注入)
$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)";
$stmt = $conn->prepare($sql);
// 绑定参数(s = 字符串)
$stmt->bind_param("sss", $firstname, $lastname, $email);
// 执行语句
if ($stmt->execute()) {
// 获取插入记录的 ID
$last_id = $conn->insert_id;
echo "新记录创建成功。最后插入的 ID 是: " . $last_id;
} else {
// 注意:启用异常后,对于执行错误,可能不会到达此 else 分支。
echo "Error executing statement.";
}
// 关闭预处理语句
$stmt->close();
} catch (mysqli_sql_exception $e) {
echo "Error: " . $e->getMessage();
} finally {
// 始终关闭连接
if (isset($conn) && $conn instanceof mysqli) {
$conn->close();
}
}
?>

关键部分:$last_id = $conn->insert_id; 在 $stmt->execute() 成功后检索 ID。

PDO (PHP Data Objects) 提供了访问各种数据库的一致接口。由于其灵活性和对命名占位符的支持,通常更受青睐。

<?php
$servername = "localhost";
$username = "your_username"; // 替换为您的数据库用户名
$password = "your_password"; // 替换为您的数据库密码
$dbname = "myDBPDO"; // 替换为您的数据库名
$charset = 'utf8mb4';
// 数据源名称 (DSN)
$dsn = "mysql:host=$servername;dbname=$dbname;charset=$charset";
// PDO 选项
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 以异常形式开启错误报告
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 将默认的 fetch 模式设为关联数组
PDO::ATTR_EMULATE_PREPARES => false, // 禁用预处理语句的模拟以提高安全性
];
$firstname = 'Mary';
$lastname = 'Moe';
$email = 'mary.moe@example.com';
$conn = null; // 初始化连接变量
try {
// 创建 PDO 实例
$conn = new PDO($dsn, $username, $password, $options);
// 使用命名占位符准备预处理语句
$sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES (:fname, :lname, :email)";
$stmt = $conn->prepare($sql);
// 绑定值并执行
$stmt->execute([
'fname' => $firstname,
'lname' => $lastname,
'email' => $email
]);
// 获取插入记录的 ID
$last_id = $conn->lastInsertId();
echo "使用 PDO 新记录创建成功。最后插入的 ID 是: " . $last_id;
} catch (PDOException $e) {
// 处理潜在错误
echo "数据库错误: " . $e->getMessage();
// 在实际应用中,应记录错误而不是直接输出详细信息
// die(); // 可选:在发生严重错误时终止脚本
} finally {
// 当脚本结束或 $conn 设置为 null 时,PDO 连接会自动关闭。
// $conn = null; // 如果需要提前关闭,可以显式设置
}
?>

关键部分:$last_id = $conn->lastInsertId(); 在 $stmt->execute() 成功后检索 ID。

注意:这两个示例现在都包含了预处理语句和使用异常进行的基本错误处理,这些是数据库交互中至关重要的现代实践。