可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I've found a few answers for this using mySQL alone, but I was hoping someone could show me a way to get the ID of the last inserted or updated row of a mysql DB when using PHP to handle the inserts/updates.
Currently I have something like this, where column3 is a unique key, and there's also an id column that's an autoincremented primary key:
$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 is correct on INSERT, but incorrect when it's updating a row (ON DUPLICATE KEY UPDATE).
I have seen several posts with people advising that you use something like
INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)
to get a valid ID value when the ON DUPLICATE KEY is invoked-- but will this return that valid ID to the PHP mysql_insert_id()
function?
回答1:
Here's the answer, as suggested by Alexandre:
when you use the id=LAST_INSERT_ID(id) it sets the value of mysql_insert_id = the updated ID-- so your final code should look like:
<?
$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();
This will return the right value for $my_id regardless of update or insert.
回答2:
You could check if the Query was an insert or an update ( mysql_affected_rows(); returns 1 on insert and 2 on update).
If it was an insert use mysql_insert_id, if it was an update you'd need another Query.
<?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 ...
}
?>
I know it's not excatly what your looking for but it's the best i could come up with
回答3:
Although not using mysql_insert_id() and ON DUPLICATE KEY UPDATE, alternative great way to get the value of any field when updating another found here:
UPDATE table SET id=(@tempid:=id) , .... LIMIT 1;
SELECT @tempid;
I used it having table with (id,status) 'id' primary index auto-increment, and 'status' was the field upon which update was made, but i needed to get 'id' of the updated row. This solution also proof to race conditions as mysql_insert_id().
回答4:
This is my solution where you put the data into a single array and it's automatically duplicated/populated into the "INSERT INTO .. ON DUPLICATE UPDATE .. " query.
It's great for maintainability, and if you want you can make it a function / method too.
// 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)))) ;