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

时间:2012-05-17 22:42:30

标签: php mysql

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

当客户下订单时,第一个条目进入sales_order表并基于auto_increment表的sales_order id,相应的条目进入{ {1}}表。

我正在使用sales_order_details MySql函数从last_insert_id()表中检索相应的order_id,像这样。

sales_order

它正在运作。 insert into sales_order_details(order_id, prod_id, prod_price)values(last_insert_id(), 5, 1500); 函数从相应的表中检索最后一个插入的id,这对于特定连接是唯一的(据我所知)。

现在,我需要last_insert_id()最近检索并插入的order_id last_insert_id(),以便将其作为发票号发送给付款系统。

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

7 个答案:

答案 0 :(得分:1)

您可以解决此问题 2种方式

在sales_order中插入条目后:

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

  2. last_insert_id存储在MySql user-defined variable中,并使用查询中的变量代替last_insert_id

  3. 选项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);`
    

答案 1 :(得分:1)

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

是您要寻找的房产。它完全可靠。

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

答案 2 :(得分:1)

* 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”。

答案 3 :(得分:0)

mysql_insert_id( )始终返回上一个查询为AUTO_INCREMENT列生成的ID。 (见PHP Manual

我不确切地知道您要获取哪个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变量中的优点是,您的系统或框架在您不知道的情况下执行其他查询时不会弄乱您的查询。

答案 4 :(得分:0)

您可能希望稍微重新构建一下您的查询。

  1. 将记录插入sales_order表格
  2. 使用php函数mysql_insert_id()来检索sales_order记录的ID:$sales_order_id = mysql_insert_id()
  3. 重写您的插件,如下所示:`insert into sales_order_details(order_id,prod_id,prod_price)values($ sales_order_id,5,1500);

答案 5 :(得分:0)

在insering sales_order之后立即使用mysql_insert_id()。你没事。

答案 6 :(得分:0)

 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;
    ?>