0

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

当客户下订单时,将第一个条目放入sales_order表中,并根据表的auto_incrementidsales_order将相应的条目放入sales_order_details表中。

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

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

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

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

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

4

7 回答 7

1

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

在 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);`
于 2012-05-17T22:45:49.013 回答
1

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

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

mysql_insert_id(和所有 mysql_ 函数)已被弃用。

于 2012-05-17T22:46:51.080 回答
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”。

于 2012-05-17T22:50:31.950 回答
0

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 变量中的好处是,您的系统或框架不会在您不知道的情况下通过执行另一个查询来弄乱您的查询。

于 2012-05-17T22:46:03.860 回答
0

您可能想稍微重构一下查询。

  1. 将记录插入sales_order表中
  2. 使用 php 函数mysql_insert_id()检索记录的 id sales_order$sales_order_id = mysql_insert_id()
  3. 像这样重写您的插入:`insert into sales_order_details(order_id, prod_id, prod_price)values($sales_order_id, 5, 1500);
于 2012-05-17T22:46:51.200 回答
0

只需mysql_insert_id()在插入 sales_order 后立即使用。你会没事的。

于 2012-05-17T22:46:57.450 回答
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;
    ?> 
于 2016-03-30T10:31:01.283 回答