使用 PHP 从 MySql 检索最后一个插入 ID


Retrieving the last insert id from MySql using PHP

我在MySql数据库中有两个表,一个是sales_order的,另一个是sales_order_details的,其中包含sales_order表中订单的详细信息。显然,从sales_ordersales_order_details存在一对多的关系。

当客户下订单时,第一个条目进入sales_order表,并根据sales_order表的auto_increment ID将相应的条目输入sales_order_details表。

我正在使用 last_insert_id() MySql 函数从sales_order表中检索相应的order_id,如下所示。

insert into sales_order_details(order_id, prod_id, prod_price)values(last_insert_id(), 5, 1500);

它正在工作。last_insert_id()函数从相应的表中检索最后插入的id,该id对于特定连接是唯一的(据我所知(。

现在,我需要与最近由last_insert_id()函数检索和插入的相同order_id将其作为发票编号发送到支付系统。

我可以尝试使用 PHP 函数mysql_insert_id()但我不确定它是否按指定工作。检索最后一个插入 ID 的正确方法是什么,它始终保证检索始终与特定订单关联的特定 ID?

有两种方法可以解决这个问题:

在sales_order中插入条目后:

  1. 获取last_insert_id并将其存储在 php 变量中,然后将此值注入相关查询中。

  2. last_insert_id存储在 MySql 用户定义的变量中,并在查询中使用该变量而不是 last_insert_id

选项 2 的示例代码

SET @last_order_id = last_insert_id();

insert into sales_order_details (order_id, prod_id, prod_price)
values (@last_order_id, 5, 1500);`
insert into sales_invoice (order_id, invoice_id)
values (@last_order_id, 1);`

> http://ca.php.net/manual/en/mysqli.insert-id.php

是您正在寻找的财产。它是完全可靠的。

mysql_insert_id(以及所有mysql_函数(已弃用。

*LAST_INSERT_ID((* 和 *mysql_insert_id((* 都像通告的那样工作,即:它们将检索当前会话/连接期间插入到任何表中的最后一个 ID。

只要在检索此 id 之前不要插入到多个自动递增表中,就可以确定它是正确的。

在同一个表中插入多个值时也要小心,您将收到其中第一个值的值,但它们不一定是连续的(不同的会话/连接也可能插入一些新记录(。

我通常喜欢做这样的事情:

START TRANSACTION;
    INSERT INTO sales_order ...;
    SET @last_order = LAST_INSERT_ID();
    INSERT INTO sales_order_details (order_id) VALUES ($last_order);
    SELECT @last_order;
COMMIT;

此查询的结果集应包含保存最后一个订单值的单个列和单个行。

但话又说回来,我通常这样做是为了更新的交易安全。

START TRANSACTION;
    SELECT * FROM sales_order WHERE order_id = 2 FOR UPDATE;
    UPDATE sales_order_details SET quantity = 9 WHERE order_id = 2 AND prod_id = 3;
    UPDATE sales_order SET price_to_pay = (SELECT SUM(quantity*price) FROM sales_order_details WHERE order_id = 2);
COMMIT;

事务应确保操作是原子的(所有操作均未被其他进程中断(;

如果您在没有交易或从应用程序代码中执行相同的操作,则数量可能会在完成更新价格之前由另一个线程更新并由第三个线程读取。向用户生成错误的"price_to_pay"。

您可能希望稍微重组一下查询。

  1. 将记录插入到sales_order表中
  2. 使用 php 函数 mysql_insert_id() 检索sales_order记录的 id:$sales_order_id = mysql_insert_id()
  3. 像这样重写你的插入:"插入到sales_order_details(order_id, prod_id, prod_price(values($sales_order_id, 5, 1500(;
只需在

输入sales_order后立即使用mysql_insert_id()即可。你会没事的。

mysql_insert_id( )始终返回由上一个查询为AUTO_INCREMENT列生成的 id。(参见 PHP 手册(

我不确切了解您要获取哪个id,但是为了使用PHP检索它,您应该始终在查询后直接执行此操作。例如:

// Query A
mysql_query( 'INSERT INTO table_a ( id, name ) VALUES ( NULL, "Henry" )' );
$idA = mysql_insert_id( );
// Query B
mysql_query( 'INSERT INTO table_b ( id, name, a_id ) VALUES ( NULL, "Wotton", ' . $idA . ' )' );
$idB = mysql_insert_id( );
// Query C
mysql_query( 'INSERT INTO table_c ( id, name, a_id ) VALUES ( NULL, "Rick", ' . $idA . ' )' );

将它们存储在 PHP 变量中的优点是,您的系统或框架不会在您不知道的情况下通过执行另一个查询来弄乱您的查询。

 1. Database
    CREATE TABLE MyGuests (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    firstname VARCHAR(30) NOT NULL,
    lastname VARCHAR(30) NOT NULL,
    email VARCHAR(50),
    reg_date TIMESTAMP
    )

-------------------------------------------------------------------
  1.   Example (MySQLi Object-oriented)
-------------------------------------------------------------------
    <?php
    $servername = "localhost";
    $username = "username";
    $password = "password";
    $dbname = "myDB";
    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }
    $sql = "INSERT INTO MyGuests (firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')";
    if ($conn->query($sql) === TRUE) {
        $last_id = $conn->insert_id;
        echo "New record created successfully. Last inserted ID is: " . $last_id;
    } else {
        echo "Error: " . $sql . "<br>" . $conn->error;
    }
    $conn->close();
    ?>
------------------------------------------------------------------- 
   2.  Example (MySQLi Procedural)
-------------------------------------------------------------------
    <?php
    $servername = "localhost";
    $username = "username";
    $password = "password";
    $dbname = "myDB";
    // Create connection
    $conn = mysqli_connect($servername, $username, $password, $dbname);
    // Check connection
    if (!$conn) {
        die("Connection failed: " . mysqli_connect_error());
    }
    $sql = "INSERT INTO MyGuests (firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')";
    if (mysqli_query($conn, $sql)) {
        $last_id = mysqli_insert_id($conn);
        echo "New record created successfully. Last inserted ID is: " . $last_id;
    } else {
        echo "Error: " . $sql . "<br>" . mysqli_error($conn);
    }
    mysqli_close($conn);
    ?>
------------------------------------------------------------------- 
  3.  Example (PDO)
-------------------------------------------------------------------
    <?php
    $servername = "localhost";
    $username = "username";
    $password = "password";
    $dbname = "myDBPDO";
    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
        // set the PDO error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $sql = "INSERT INTO MyGuests (firstname, lastname, email)
        VALUES ('John', 'Doe', 'john@example.com')";
        // use exec() because no results are returned
        $conn->exec($sql);
        $last_id = $conn->lastInsertId();
        echo "New record created successfully. Last inserted ID is: " . $last_id;
        }
    catch(PDOException $e)
        {
        echo $sql . "<br>" . $e->getMessage();
        }
    $conn = null;
    ?>