Получение 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()
?
Ответы
Ответ 1
Здесь ответ, предложенный Александром:
когда вы используете 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 независимо от обновления или вставки.
Ответ 2
Вы можете проверить, был ли запрос вставкой или обновлением (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 ...
}
?>
Я знаю, что это не оправдано, что вы ищете, но это лучшее, что я мог придумать
Ответ 3
Хотя не использовать mysql_insert_id() и ON DUPLICATE KEY UPDATE, альтернативный отличный способ получить значение любого поля при обновлении другого найденного здесь:
UPDATE table SET id=(@tempid:=id) , .... LIMIT 1;
SELECT @tempid;
Я использовал его с таблицей с индексом (id, status) 'id' primary index auto-increment, а "status" было полем, на котором было произведено обновление, но мне нужно было получить "id" обновленной строки. Это решение также подтверждает условия гонки как mysql_insert_id().
Ответ 4
Это мое решение, в котором вы помещаете данные в один массив и автоматически дублируется/заполняется в запросе "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 (".
// i.e 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 (".
// i.e '20', '532', '600' ..
implode(", \n", array_map(function($v){ return "'$v'"; }, array_values($qData)))
." ) ON DUPLICATE KEY UPDATE ".
// i.e `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)))) ;