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

发布于 2024-10-10 22:13:55 字数 346 浏览 4 评论 0原文

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

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

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

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

If I insert multiple records with a loop that executes a single record insert, the last insert id returned is, as expected, the last one. But if I do a multiple records insert statement:

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

Let's say the three above are the first records inserted in the table. After the insert statement I expected the last insert id to return 3, but it returned 1. The first insert id for the statement in question.

So can someone please confirm if this is the normal behavior of LAST_INSERT_ID() in the context of multiple records INSERT statements. So I can base my code on it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南…巷孤猫 2024-10-17 22:13:55

是的。 last_insert_id() 的这种行为是 MySQL 文档中记录

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

Yes. This behavior of last_insert_id() is documented in the MySQL docs:

Important
If you insert multiple rows using a single INSERT statement, LAST_INSERT_ID() returns the value generated for the first inserted row only. The reason for this is to make it possible to reproduce easily the same INSERT statement against some other server.

甜味超标? 2024-10-17 22:13:55

手册页中提到了此行为MySQL。它在评论中,但没有受到质疑,所以我猜测这是预期的行为。

This behavior is mentioned on the man page for MySQL. It's in the comments but is not challenged, so I'm guessing it's the expected behavior.

无人问我粥可暖 2024-10-17 22:13:55

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

  1. 在插入之前获取“Before MAX(ID)”:
    SELECT MAX(id) AS before_max_id FROM table_name`
  1. 使用数据进行多个 INSERT ... VALUES () 查询并保留它们:

    插入表名
    (第 1 列,第 2 列)
    价值观 
    (“值1-1”,“值1-2”), 
    (“值2-1”,“值2-2”), 
    (“值3-1”,“值3-2”), 
    关于重复密钥更新
    
  2. 在插入后立即获取“After MAX(ID)”:

    SELECT MAX(id) AS after_max_id FROM table_name`
    
  3. 获取 ID 介于“Before MAX(ID)”和“After 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()。

I think it's possible if your table has unique autoincrement column (ID) and you don't require them to be returned by mysql itself. I would cost you 3 more DB requests and some processing. It would require these steps:

  1. Get "Before MAX(ID)" right before your insert:
    SELECT MAX(id) AS before_max_id FROM table_name`
  1. Make multiple INSERT ... VALUES () query with your data and keep them:

    INSERT INTO table_name
    (col1, col2)
    VALUES 
    ("value1-1" , "value1-2"), 
    ("value2-1" , "value2-2"), 
    ("value3-1" , "value3-2"), 
    ON DUPLICATE KEY UPDATE
    
  2. Get "After MAX(ID)" right after your insert:

    SELECT MAX(id) AS after_max_id FROM table_name`
    
  3. Get records with IDs between "Before MAX(ID)" and "After MAX(ID)" including:

    SELECT * FROM table_name WHERE id>$before_max_id AND id<=$after_max_id`
    
  4. Do a check of retrieved data with data you inserted to match them and remove any records that were not inserted by you. The remaining records have your IDs:

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

This is just how a common person would solve it in a real world, with parts of code. Thanks to autoincrement it should get smallest possible amount of records to check against, so they will not take lot of processing. This is not the final "copy & paste" code - eg. you have to create your own function compare_content() according you your needs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文