MySQL - Rows matched


MySQLでUpdate文を走らせた結果、こんな情報が最終行に表示されます。

Rows matched: 1 Changed: 1 Warnings: 0


もう一度同じUPDATE文を走らせるとこうなります。

Rows matched: 1 Changed: 0 Warnings: 0


該当行は存在するが、更新されなかったということです。

MySQLマニュアル
カラムの値がそのカラムの現在の値に設定される場合、MySQL はそれが現在の値であることを認識し、更新処理を行いません。


通常、PHPなどで更新された行数を返す関数は、Rows Changedの値を返します。


つまり、

PHPマニュアル
ゼロが返された場合、それは UPDATE 文でレコードが更新されなかったか WHERE 条件に当てはまる行がなかった、またはクエリが実行されなかったことを 示します。


更新すべき行があるのに、値が同じだったためにエラー(ゼロ)を返されては困る場合、mysql_real_connectMYSQL_CLIENT_FOUND_ROWSフラグを立てることで、Rows ChangedではなくRows Matchedの値を取ることができます。


しかーし、私が今回試用しているPDO(データベースアクセスモジュール)では、CLIENT_FOUND_ROWSがサポートされていない(参照)のでした。


そこで代替案。

  1. 当該UPDATEのエラーチェックをしない
  2. PDOを使わない
  3. PDOの内部でconnectしている箇所を書き換える
  4. UPDATEの際にダミーテーブルを同時に更新して*1、必ず返り値が1以上になるようにする


これらは各々の理由で却下されました。


結果的には、UPDATEでゼロが返ってきたら(確率としてはほぼ0)、SELECT文で本当に更新する行がないのか調べ、SELECT結果でもゼロが返ってきたらエラー処理をすることになりました。

*1:例:UPDATE someTable, dummyTable SET someTable.someColumn='hogege', dummyTable.dummyColumn=dummyTable.dummyColumn+1