web-dev-qa-db-ja.com

PHP)でON DUPLICATE KEY UPDATEを使用しているときにmysql_insert_id()を取得する

MySQLだけを使用してこれに対するいくつかの答えを見つけましたが、PHP挿入/更新を処理します。

現在、私はこのようなものを持っています。ここで、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 KEYUPDATE)。

私はあなたが次のようなものを使用することをアドバイスする人々とのいくつかの投稿を見ました

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

oN DUPLICATE KEYが呼び出されたときに有効なID値を取得しますが、これにより、その有効なIDがPHP mysql_insert_id()関数に返されますか?

25
julio

アレクサンドルが提案した答えは次のとおりです。

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に適切な値が返されます。

37
julio

クエリが挿入であるか更新であるかを確認できます(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 ... 
}
?>

私はそれがあなたが探しているものではないことを知っていますが、それは私が思いつくことができる最高のものです

10
edorian

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()として競合状態を証明するものでもあります。

1
satih

これは、データを単一の配列に配置し、「INSERT INTO .. ON DUPLICATEUPDATE ..」クエリに自動的に複製/入力される私のソリューションです。

保守性に優れており、必要に応じて関数/メソッドにすることもできます。

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