получение mysql_insert_id () при использовании ON DUPLICATE KEY UPDATE с PHP

Я нашел несколько ответов для этого, используя только mySQL, но я надеялся, что кто-то сможет показать мне способ получить идентификатор последней вставленной или обновленной строки базы данных mysql при использовании PHP для обработки вставок / обновлений.

В настоящее время у меня есть что-то вроде этого, где column3 – уникальный ключ, а также столбец идентификатора, который является автоинкрементным первичным ключом:

$query ="INSERT INTO TABLE (column1, column2, column3) VALUES (value1, value2, value3) ON DUPLICATE KEY UPDATE SET column1=value1, column2=value2, column3=value3"; mysql_query($query); $my_id = mysql_insert_id(); 

$ my_id верен в INSERT, но неверен, когда он обновляет строку (ON DUPLICATE KEY UPDATE).

Я видел несколько сообщений с людьми, которые советуют вам использовать что-то вроде

 INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id) 

для получения действительного значения ID при вызове ключа ON DUPLICATE KEY – но вернет ли этот действительный идентификатор функции PHP mysql_insert_id() ?

Вот ответ, предложенный Александром:

когда вы используете id = LAST_INSERT_ID (id), он устанавливает значение mysql_insert_id = обновленный идентификатор, поэтому ваш окончательный код должен выглядеть так:

 <? $query = mysql_query(" INSERT INTO table (column1, column2, column3) VALUES (value1, value2, value3) ON DUPLICATE KEY UPDATE column1 = value1, column2 = value2, column3 = value3, id=LAST_INSERT_ID(id) "); $my_id = mysql_insert_id(); 

Это вернет правильное значение для $ my_id независимо от обновления или вставки.

Вы можете проверить, был ли запрос вставкой или обновлением (mysql_affected_rows (), возвращает 1 на вставке и 2 при обновлении).

Если это была вставка, используйте mysql_insert_id, если это было обновление, вам понадобится другой запрос.

 <?php $query ="INSERT INTO TABLE (column1, column2, column3) VALUES (value1, value2, value3) ON DUPLICATE KEY UPDATE SET column1=value1, column2=value2, column3=value3"; mysql_query($query); if(mysql_affected_rows() == 1) { $id = mysql_insert_id(); } else { // select ... } ?> 

Я знаю, что это не значит, что вы ищете, но это лучшее, что я могу придумать

Хотя не использовать mysql_insert_id () и ON DUPLICATE KEY UPDATE, альтернативный отличный способ получить значение любого поля при обновлении другого, найденного здесь :

 UPDATE table SET id=(@tempid:=id) , .... LIMIT 1; SELECT @tempid; 

Я использовал его с таблицей с (id, status) «id» первичного индекса auto-increment, а «status» – это поле, на котором было произведено обновление, но мне нужно было получить «id» обновленной строки. Это решение также подтверждает условия гонки как mysql_insert_id ().

Это мое решение, когда вы помещаете данные в один массив, и он автоматически дублируется / заполняется в запросе «INSERT INTO .. ​​ON DUPLICATE UPDATE ..».

Он отлично подходит для ремонтопригодности, и если вы хотите, вы можете сделать его функцией / методом.

 // save to db: $qData = [ "id" => mysql_real_escape_string($email_id), "synd_id" => mysql_real_escape_string($synd_id), "campaign_id" => mysql_real_escape_string($campaign_id), "event_id" => mysql_real_escape_string($event_id), "user_id" => mysql_real_escape_string($user_id), "campaign_name" => mysql_real_escape_string($campaign_name), "subject" => mysql_real_escape_string($subject), "from_name"=> mysql_real_escape_string($from_name), "from_email"=> mysql_real_escape_string($from), "content"=> mysql_real_escape_string($html), "link_to_template" => mysql_real_escape_string($hash), "ext_campaign_id" => mysql_real_escape_string($ext_campaign_id), "ext_list_id"=> mysql_real_escape_string($ext_list_id), ]; $q = "INSERT INTO email_campaigns (". // ie create a string like `id`, `synd_id`, `campaign_id`.. with linebreaks for readability implode(", \n", array_map(function($k){ return "`$k`"; }, array_keys($qData))) .") VALUES (". // ie '20', '532', '600' .. implode(", \n", array_map(function($v){ return "'$v'"; }, array_values($qData))) ." ) ON DUPLICATE KEY UPDATE ". // ie `synd_id`='532', `campaign_id`='600' ... // id & link_to_template table keys are excluded based on the array below implode(", \n", array_filter(array_map(function($k, $v){ if(!in_array($k, ['id', 'link_to_template']) ) return "`$k`='$v'" ; }, array_keys($qData), array_values($qData)))) ;