MySQL LAST_INSERT_ID()与多个记录INSERT语句一起使用

时间:2011-01-09 02:41:49

标签: mysql insert lastinsertid

如果我使用执行单个记录插入的循环插入多个记录,则返回的最后一个插入ID是预期的最后一个。但是如果我做一个多记录插入语句:

INSERT INTO people (name,age)
VALUES ('William',25), ('Bart',15), ('Mary',12);

假设上面三个是表中插入的第一个记录。在insert语句之后我期望最后一个插入id返回3,但它返回1.所讨论语句的第一个插入id。

有人可以在多个记录INSERT语句的上下文中确认这是否是LAST_INSERT_ID()的正常行为。所以我可以将代码基于它。

3 个答案:

答案 0 :(得分:39)

是。 last_insert_id()的此行为为documented in the MySQL docs

  

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

答案 1 :(得分:2)

在MySQL man page上提到了这种行为。它在评论中但没有受到挑战,所以我猜它是预期的行为。

答案 2 :(得分:0)

我认为如果您的表具有唯一的自动增量列(ID),并且您不要求它们由mysql本身返回,则是可能的。我要再花3个数据库请求和一些处理。它将需要以下步骤:

  1. 在插入之前获取“在MAX(ID)之前”:
    SELECT MAX(id) AS before_max_id FROM table_name`
  1. 对您的数据进行多个INSERT ... VALUES()查询,并将其保存:

    INSERT INTO table_name
    (col1, col2)
    VALUES 
    ("value1-1" , "value1-2"), 
    ("value2-1" , "value2-2"), 
    ("value3-1" , "value3-2"), 
    ON DUPLICATE KEY UPDATE
    
  2. 在插入后立即获取“ MAX(ID)之后”:

    SELECT MAX(id) AS after_max_id FROM table_name`
    
  3. 获取ID在“ MAX(ID)之前”和“ MAX(ID)之后”之间的记录,包括:

    SELECT * FROM table_name WHERE id>$before_max_id AND id<=$after_max_id`
    
  4. 检查检索到的数据是否与您插入的数据相匹配,并删除所有您未插入的记录。其余记录具有您的ID:

    foreach ($after_collection as $after_item) {
      foreach ($input_collection as $input_item) {
        if ( $after_item->compare_content($input_item) ) {
          $intersection_array[] = $after_item;
        }
      }
    }

这就是普通人使用部分代码在现实世界中解决问题的方式。多亏了自动增量功能,它应该可以获得尽可能少的记录以进行检查,因此它们不会花费很多处理。这不是最终的“复制和粘贴”代码-例如。您必须根据自己的需要创建自己的函数compare_content()。