在PHP上使用ON DUPLICATE KEY UPDATE时获取mysql_insert_id()

时间:2010-04-14 00:34:40

标签: php mysql mysql-insert-id

我已经使用mySQL单独找到了一些答案,但我希望有人可以告诉我一种方法来获取使用PHP处理插入/更新时mysql数据库的最后插入或更新行的ID

目前我有这样的东西,其中column3是一个唯一的密钥,并且还有一个id列,它是一个自动增加的主键:

$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) 

在调用ON DUPLICATE KEY时获取有效的ID值 - 但这会将该有效ID返回给PHP mysql_insert_id()函数吗?

4 个答案:

答案 0 :(得分:35)

这是亚历山大建议的答案:

当你使用id = LAST_INSERT_ID(id)时,它设置了mysql_insert_id =更新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的正确值。

答案 1 :(得分:10)

您可以检查Query是插入还是更新(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 ... 
}
?>

我知道你所寻找的并不是什么,但这是我能想到的最好的

答案 2 :(得分:1)

虽然没有使用mysql_insert_id()和ON DUPLICATE KEY UPDATE,但在更新另一个字段时获取任何字段值的另一种好方法是here

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

我使用了具有(id,status)'id'主索引自动增量的表,'status'是进行更新的字段,但我需要得到更新行的'id'。该解决方案还证明竞争条件为mysql_insert_id()。

答案 3 :(得分:0)

这是我的解决方案,您可以将数据放入单个数组中,并自动复制/填充到&#34; INSERT INTO .. ON DUPLICATE UPDATE ..&#34;查询。

它非常适合可维护性,如果你想要,你也可以使它成为一个功能/方法。

// 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))))  ;