26

我已经找到了一些单独使用 mySQL 的答案,但我希望有人可以告诉我一种方法来获取使用 PHP 处理插入/更新时最后插入或更新的 mysql DB 行的 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 上是正确的,但在更新行时不正确(在 DUPLICATE KEY UPDATE 上)。

我看过一些帖子,有人建议你使用类似的东西

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

在调用 ON DUPLICATE KEY 时获取有效 ID 值——但这会将有效 ID 返回给 PHPmysql_insert_id()函数吗?

4

4 回答 4

39

正如亚历山大所建议的,这是答案:

当您使用 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 的正确值。

于 2010-04-16T01:41:42.353 回答
10

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

我知道这不是您要寻找的东西,但这是我能想到的最好的

于 2010-04-14T10:08:43.980 回答
1

虽然不使用 mysql_insert_id() 和 ON DUPLICATE KEY UPDATE,但在更新另一个字段时获取任何字段值的另一种好方法在这里找到:

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

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

于 2014-03-02T15:29:15.050 回答
0

这是我的解决方案,您将数据放入单个数组中,并自动复制/填充到“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))))  ;
于 2016-08-08T01:17:23.693 回答