• 締切済み

ON DUPLICATE KEY UPDATE

こんにちは。 PHP + MYSQL でシステム構築をしております。 この度は、新しいレコードを INSERT するが、もしもINSERT するレコードのうちの主キーが既に存在する場合は、UPDATE を行うという処理をしたいと思っています。 調べているうちに MySQL 4.1.0 の新機能である ON DUPLICATE KEY UPDATE 節というものがありましたが、4.1.0以前の MYSQL を利用の場合はどのようにするのが最適でしょうか? 私が考えたのは、挿入前に主キーを持つレコードを読み込んで、レコードが返ってこなかった場合は INSERT、何かレコードが返ってきた場合は UPDATE というようにする方法ですが、少し回りくどい気もします。 クエリのみで、またはシンプルな方法でこれを解決する方法はありますでしょうか? ご教授お願いいたします。

みんなの回答

  • hisappy
  • ベストアンサー率46% (184/392)
回答No.3

UPDATEの方が頻繁なのであり、 SQL構文エラーなどにも対応するようにとなれば ret = UPDATE~~~; if( 更新エラーだったら == ret) {   ret = INSERT~~~;   if( エラーだったら == ret)   {     //エラー処理   } } else {   //構文エラー処理 } こんな具合でしょうか。 リターンコードが別々で帰ってくるのかどうかまでは 知らないので、補完願います。

shu_a
質問者

お礼

ご回答ありがとうございます。 おそらくエラーは一元化されているように感じますが、 当方は PEAR を用いていますので、エラーコードが振り分けされるようです。 参考にさせていただきました。

  • cojirou
  • ベストアンサー率50% (59/117)
回答No.2

試行してないのでうまく行くか分かりませんが…。 もしも、複数データを一度にDatabaseに入力しようとしてるなら、 $ary1 = array(入力しようとするデータの主キーの配列); $ary2 = array(Database上に既にあるデータの主キーの配列); $up_ary = array_intersect($ary1, $ary2); $ins_ary = array_diff($array1, $array2); とすると、$up_aryはDatabaseにあるもの、$ins_aryはないものにできるかも。 あとは、$up_ary、$ins_ary をそれぞれforeachかけて、 それぞれクエリ文を作るなど。 1個ずつデータ入力するなら上記の$ary2だけ使って、array_searchを使ったり。 array_search、array_intersect、array_diff  については当方では動作確認していませんので、 くわしくはマニュアルをお読みください。 あまりシンプルでもないですが、ご参考までに。

参考URL:
http://www.php.net/manual/ja/ref.array.php
shu_a
質問者

お礼

スクリプト側で処理する方法もあることを参考にさせていただきました。 ありがとうございました。

shu_a
質問者

補足

ご回答ありがとうございます。 そしてご返信が遅くなりまして申し訳ございません。 さて、$ary2 を知るためには、予めクエリを発行しなければいけないような気がします。 そして、挿入するデータに同じ主キーを含むものがあればとなるとさらに大変です。 またデータ量が増えるにしたがって、配列のサイズが大きくなってしまい、データベースの特性がうまく活かせません。 今回は、既にデータベース上にあるレコードに対して、挿入もしくは更新をシンプルに行う目的としています。 よろしくお願いします。

  • hisappy
  • ベストアンサー率46% (184/392)
回答No.1

主キーということは、DBにてプライリマリキー設定されていると考えてよろしいのでしょうか? それなら同じ主キーのものをINSERTしようとするとエラーになるので、 INSERT~~~; if( エラーだったら) {   UPDATE~~~; } という少々強引なやり方をした事があります。 (構文は補完願います) プライマリキー設定されていないなら、仰っているように 一旦SELECTするやり方しかないでしょう。

shu_a
質問者

お礼

ご回答ありがとうございます。 その通りです。プライマリキーを設定しています。 なのでエラーを取得する方法も有効と思います。 でも構文エラーなどの各種エラーが発生した場合には混同してしまうので困るような気がします。 SELECT を用いると DBへのアクセス回数が増えてしまいます。UPDATE を頻繁に行うような場合だとリソースの無駄遣いになってしまいますのでもう少しシンプルな方法はありませんでしょうか?

関連するQ&A

専門家に質問してみよう