PDO - 用于多个插入查询的lastInsertId()

时间:2012-09-25 00:21:23

标签: mysql pdo lastinsertid last-insert-id

我可以将2只宠物插入表中,并获取它们的lastInsertId(),以便一次进行一次处理(2次查询)。
我想知道如果我在1个查询中插入2行,是否有办法获取两个lastInsertIds()并将它们分配给变量:

$query = "INSERT INTO pets (pet_name) VALUES (':coco'),(':jojo')";
$pet_insert = $dbh->prepare($query);
$pet_insert->execute(array(':coco' => $coco,':jojo' => $jojo));
$New_PetID = $dbh->lastInsertId();

是否可以为coco和jojo获取lastInsertId()?如下所示:

$New_PetID1 = $dbh->lastInsertId();//coco
$New_PetID2 = $dbh->lastInsertId();//jojo

这将提供相同的ID,以获得2个ID的任何方式?仅供参考,这是一个尝试块。

10 个答案:

答案 0 :(得分:14)

这是不可能的。如果您需要为两行生成ID,则需要执行2个单独的INSERT

  

重要如果使用单个INSERT语句插入多行,   LAST_INSERT_ID()返回为首次插入生成的值   仅排。这样做的原因是可以重现   与其他服务器轻松相同的INSERT语句。

http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id

答案 1 :(得分:5)

你可以添加1到最后一个插入id以实现真正的最后一个记录id。如果你插入超过2个记录,只需将rowCount - 1添加到last_insert_id。

  

当innodb_autoinc_lock_mode设置为0(“传统”)或1(“连续”)时,任何给定语句生成的自动递增值将是连续的,没有间隙,因为表级别的AUTO-INC锁定一直保持到语句的结尾,一次只能执行一个这样的语句。

  

生成的ID基于每个连接在服务器中维护。这意味着函数返回给定客户端的值是为该客户端影响AUTO_INCREMENT列的最新语句生成的第一个AUTO_INCREMENT值。此值不受其他客户端的影响,即使它们生成自己的AUTO_INCREMENT值。此行为可确保每个客户端都可以检索自己的ID,而无需关心其他客户端的活动,也无需锁定或事务。

了解更多信息,请阅读此文档http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html

答案 2 :(得分:3)

请避免布鲁斯给出的解决方案。自动增量值可以设置为不同于1.例如,在主从复制的情况下。一段时间后,我们运行其中一个应用程序的主机改变了它们的数据库设置。我偶然注意到 - 巧合 - 突然间,id增加了两个而不是一个。我们是否有这样的代码可能会给我们带来严重的问题。

答案 3 :(得分:2)

documentation州:Returns the ID of the last inserted row or sequence value

您需要执行两个查询才能获取每个插入行的ID。

答案 4 :(得分:1)

好吧,因为1000个插入比1个插入长一点,所以主题的问题仍然很有趣。可能的解决方法是进行2次查询。第一个是插入1000行,第二个是选择它们,如果插入的行中有一些唯一的东西。 例如宠物:

INSERT INTO pets ( name ) VALUES ( 'coco', 'jojo' );
SELECT id FROM pets WHERE name IN ( 'coco', 'jojo' );

这可能只对大数据集有益。

答案 5 :(得分:0)

我试着假设这是不可能的,直到我自己尝试并认为这是可能的

  

每次执行后,添加lastInsertId()并指定一个键。

我的例子:

// First query
$sql = "INSERT INTO users
(username, email)
values
(:username, :email)";
$sth = $this->db->prepare($sql);
$sth->bindParam(':username', $data['username'], PDO::PARAM_STR);
$sth->bindParam(':email', $data['email'], PDO::PARAM_STR);

// Second Query
$sql2 = "INSERT INTO users
(username, email)
values
(:username, :email)";
$sth2 = $this->db->prepare($sql2);
$sth2->bindParam(':username', $data['username'], PDO::PARAM_STR);
$sth2->bindParam(':email', $data['email'], PDO::PARAM_STR);

// Start trans
$this->db->beginTransaction();

// Execute the two queries
$sth->execute();
$last['ux1'] = $this->db->lastInsertId(); // <---- FIRST KEY

$sth2->execute();
$last['ux2'] = $this->db->lastInsertId(); // <---- SECOND KEY

// Commit
$this->db->commit();

我能够检索最后插入的两个ID

  

阵列(       [创建] =&gt;排列           (               [ux1] =&gt; 117               [ux2] =&gt; 118           )

     

我希望这会帮助那些寻求正确答案的人。

答案 6 :(得分:0)

你可以使用&#39; multi_query()&#39; 将所有查询添加到一个变量中,如:     &#39; $ sql1 =&#34;首先插入&#34;;&#39;     &#39; $ sql2 =&#34;第二次插入&#34;;&#39;     &#39; $ sql3 =&#34;第三次插入&#34;;&#39;等等... 计算您要进行的插入次数。 现在执行所有&#39; $ sql&#39;查询使用&#39; multi_query()&#39;。 获取最后一个插入ID。 现在你所要做的就是&#39; $ rowno = $ lastinsertid - $ countofinserts&#39;。 所以基本上你会得到一个数字。 添加1并从结果数字到lastinsertid是您运行的插入查询的插入ID

答案 7 :(得分:0)

我的方法没有解决这个问题,但可能对某些类似的情况有帮助。

当我需要插入大行列表时:

  1. 我从PrimaryKey列中删除AUTO_INCREMENT,将其类型更改为BIGINT。
  2. 使用UUID_SHORT()功能准备唯一PK值列表。要使用单个查询创建列表,请使用:
  3. ( SELECT UUID_SHORT() ) UNION 
    ( SELECT UUID_SHORT() ) UNION
    ( SELECT UUID_SHORT() ) # UNION (...
    
    1. 使用此准备好的PK列表插入行。

      当我需要插入相关数据时,这种方法特别方便(例如,准备好的PK列表将用于插入连接表行)。

答案 8 :(得分:0)

我在第一条语句中使用了数组,在第二条语句中添加了if condition。因此,如果插入记录获得其最后一个ID,则进行第二条语句。如果插入第二个数组,则获得其最后一个ID,然后重复第二条语句

    for ($count=0; $count < count($_POST["laptop_ram_capacity"]); $count++) { 
        $stmt = $con->prepare('INSERT INTO `ram` 
                (ram_capacity_id, ram_type_id, ram_bus_id, ram_brand_id, ram_module_id)
                VALUES (?,?,?,?,?)');

            //excute query//
            $stmt->execute(array(
                            $_POST['laptop_ram_capacity'][$count],
                            $_POST["laptop_ram_type"][$count],
                            $_POST["laptop_ram_bus"][$count],
                            $_POST["laptop_ram_brand"][$count],
                            $_POST["laptop_ram_module"][$count]
                            ));
            //fetsh the data//
            $rows = $stmt->rowCount();
            // i add the below statment in if condition to repeat the insert and pass the repeated of the last statement//
            if ($rows > 0) {
            $LASTRAM_ID = $con->lastInsertId();

            $stmt = $con->prepare('INSERT INTO `ram_devicedesc_rel` 
                (ram_id, Parent_device_description_id)
                VALUES (?,?)');

            //excute query//
            $stmt->execute(array(
                            $LASTRAM_ID,
                            $LASTdevicedesc_ID
                            ));
            //fetsh the data//
            } else {
                echo "Error: " . $sql . "<br>" . $conn->error;
            }                                    
        }

答案 9 :(得分:-1)

有可能!您需要做的就是调用PDO lastInsertId()方法。这将在执行多个或批量INSERT时返回第一个插入的id。接下来,我们需要使用受上一个INSERT语句影响的行数执行简单的加法减法操作。

$firstInsertedId = $this->lastInsertId();
$InsertedIds = range($firstInsertedId, ($firstInsertedId + ($stmt->rowCount() - 1)) );
print_r($InsertedIds);