MySQL LAST_INSERT_ID () используется с оператором INSERT с несколькими записями - PullRequest
36 голосов
/ 09 января 2011

Если я вставляю несколько записей с циклом, который выполняет вставку одной записи, последний возвращенный идентификатор вставки, как и ожидалось, является последней.Но если я сделаю несколько операторов вставки записей:

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

Допустим, три вышеприведенных записи являются первыми записями, вставленными в таблицу.После оператора вставки я ожидал, что последний идентификатор вставки вернет 3, но он вернул 1. Первый идентификатор вставки для рассматриваемого оператора.

Так что кто-то может подтвердить, если это нормальное поведение LAST_INSERT_ID()в контексте нескольких записей операторов INSERT.Поэтому я могу основывать свой код на этом.

Ответы [ 3 ]

39 голосов
/ 01 ноября 2011

Да. Это поведение last_insert_id() задокументировано в документации MySQL :

Важно
Если вы вставляете несколько строк, используя один оператор INSERT, LAST_INSERT_ID() возвращает значение, созданное только для первой вставленной строки. Причина этого в том, чтобы можно было легко воспроизвести тот же оператор INSERT для другого сервера.

2 голосов
/ 09 января 2011

Это поведение упоминается на справочной странице для MySQL.Это в комментариях, но не оспаривается, поэтому я предполагаю, что это ожидаемое поведение.

0 голосов
/ 21 сентября 2018

Я думаю, что это возможно, если ваша таблица имеет уникальный столбец автоинкремента (ID), и вы не требуете, чтобы они возвращались самой MySQL.Я бы обошелся вам еще в 3 запроса к БД и некоторой обработке.Для этого потребуются следующие шаги:

  1. Получите «До МАКС. (ID)» прямо перед вставкой:
    SELECT MAX(id) AS before_max_id FROM table_name`

Сделайте несколько запросов 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

Получите "После MAX (ID)" сразу после вставки:

SELECT MAX(id) AS after_max_id FROM table_name`

Получение записей с идентификаторами между «До МАКС (ID)» и «После МАКС (ID)», включая:

SELECT * FROM table_name WHERE id>$before_max_id AND id<=$after_max_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 () в соответствии с вашими потребностями.

...