MySQL + UPDATE + PDOStatement::rowCount の罠

MySQLのセットアップはテーブル作成とかも含めて、非常に面倒なので、作成途中(開発中)はSQLiteで作って動作確認して、作成大詰めの段階でMySQLに切り替え完成・・・という工程はわりかし一般的?だと思う。ファイル一個でバックアップ・リストアも簡単で開発効率も上がります、僕は。

で、SQLite + PDO で何の問題もなくある程度コーディングが終わり、MySQLに移行して検証していると、おかしな挙動の解決に半日かかってしまった備忘録のエントリです。

データを空更新、特定の行を取得して、編集画面表示、その後、内容を変えずに同じデータで更新すると、update文は成功するのに、作用した行数が0を返す・・・。だいたい下のような感じ。

<?php
/*************************************************************

  あらかじめ下記mysqlクライアントで実行

  >> CREATE TABLE test_table(id INTEGER,data CHAR(255));
  >> INSERT INTO test_table values(1,'Kenji Nakagawa');

**************************************************************/
$pdo = new PDO('sqlite:log.sqlite');

if(modify_name(1,'Kenji Nakagawa'))
{
  header('location: list.php');
}

function modify_name($id,$name)
{
  global $pdo;

  $rv = false;
  $sql = 'update test_table set name = ? where id = ?';

  if(false !== ($stmt = $pdo->prepare($sql)))
    {
      if(false !== ($result = $stmt->execute(array($name,$id))))
        {
          $rv = $stmt->rowCount();
        }
    }

  return $rv;
}

この一連のコーディングでの最大の失敗は、rowCount()メソッドが返す行数で、update文の成功・失敗を判断したところ。分かってしまえば、何でもないことだけど、はまってしまった。

分かったことは、

MySQL + UPDATE文の実行では、PDOStatement::rowCount() は「実際に変更した(あった?)行数」(←ここ重要)を返す

・・・・ということ。

元々のレコードと同じデータをupdateすると、update文の実行はfalseは返さない(成功する)が、rowCount()は1ではなく、0を返す・・・。PHPサイトのドキュメントを検索したらちゃんと書いてありました・・・・とほほ(T-T)

UPDATE を使用する場合、MySQL では新旧の値が同じときには更新処理を行いません。 このことから、必ずしも mysql_affected_rows() の返す値が マッチする行の数と一致するとは限りません。返す値は実際に更新処理が行われた 行の数です。

そんな・・・・僕が勉強したときにちょろっと読んだMySQL入門書には書いてない!(笑)

ってわけで、解説書なんかで勉強するときは、いかに良い本に巡り会うことの重要性を改めて痛感しました。。。

hasOwnPropertyがない

Internet Explorer 8でチェックしてたら、window.hasOwnProperty()のところでエラーが発生。あれ?

自分の無知が恥ずかしい。。。

MSDNドキュメントをチェックしてみると、なんかドキュメントがええかげん。.hasOwnPropertyの説明では確かにIE8はサポートされない、と書いてあるんだけど・・・javascriptのバージョン情報のところを見ると、hasOwnPropertyは’Y’になっとる。

だけど、Object.hasOwnProperty はエラーは起こらず。どゆこと?

結局、IE8の時だけ、下記のようにする。

// これってもしかして、常識なの???(^^;;;
var undefined;
if(window.hasOwnProperty === undefined)
{
  window.hasOwnProperty = function(property_name)
    {
       return Object.prototype.hasOwnProperty.call(window,property_name); 
    };
}

なんか、釈然としない。はやくIE8消えてくれ。つか、会社のPC、いいかげん、XPから7にバージョンアップさせてほしい・・・自分で金出すから。

雑記

「いいね」ボタンより、「だめだめ」ボタンが欲しい今日この頃です。

7月から別の部署で、違う人の下で仕事するようになってルーチンワークが続き、好き勝手できなくなったので(^^;;;、更新が途絶えてしまいました。

備忘録するネタはあるんですが、書くのに時間がかかりなかなか終わらない。もちっと暇になったら一気に更新しよう。

あ、iPad Air が発表されましたねー。僕は128GBのものに買い替えるつもり。どうせ1~2ヶ月は品薄で手に入らないんだし、来年頭ぐらいかな、買えるのは。

どんなプラットフォームでも、プログラムを書くって、言うと、ものすごく大層なことだと、誤解されていると思うことが多々ある。は???ってことに出くわす。

「データーベースとか使って、何でプログラム組んでるの? 言語なに?」
『んー、ほとんどPHPとかPerlとかスクリプトが中心かなー。』

とか言うと、半ば、見下される(笑) 別に見下されても悔しくも何ともないんだが。
たぶん、今なら
『 Java で Webシステムの構築とか、Access、SQLServerを使って業務系組んでます!』
とか恥ずかしい事を言うと、違った反応するのかもしれないw

プログラムのスキルってのは、使用しているプログラム言語やスクリプト、プラットフォームで決まるんじゃないんだよ。
どういう内容のプログラムを組んで、どういうアプローチでシステムを構築して、どういうコードを書いているかが、その人のスキルなんだよ。どういうフレームワークで仕事してるのか、どんな分担の仕事をしてるか、チームで組んだことはあるのか、ソースコード管理は?とか。コードのメンテ性を考慮してるか?とか。
C++やマシン語が書けても、簡単なWindowsのフォームベースのプログラムに何ヶ月も掛かってたんじゃ、意味ないんだよ。そんなのはスキルじゃないんだよ!

スーパーの特売日に、フェラーリやポルシェで買いに行くような、恥ずかしい真似はしたくない、のと同じように、データベース内のたかだかテーブル数個、一日数百レコードを更新するだけようなプログラムにこれ見よがしにJavaなんか使う必要あんの?

でも、実際は、あるんだよね(笑) ちゅーと半端にシステムをかじってる営業さんは、かっこいい横文字を使えば取引先に「どや顔」できるんだよね。。。そういう世界なんだよね。僕は営業ってできない。モノを売るってことの才覚はゼロ。だから、口には出さない。だから、ここで書く!(m_m)

閑話休題。

最近はjQuery + PHP にどっぷりはまってます。いや、僕的にはjQuery + Perl ( 時々C# )にしたいのだが・・・。
Wordpressのメディアの管理画面にようなモジュールが欲しくて、イチから組んでます。

最初はデータの保存にSQLiteを使用していたけど、SQLite関数を使わずPDOを使用してたので、どうせならMySQLでも切り替えて使えるように、データへのアクセスを抽象化したところから、ちょっと変な方向に・・・。

だいたい必要なものは組み込んだけど、後から後から、あれもこれもと、機能を組み込んでいくと、あっちゅーまにワケワカメなコードが・・・。

fileman02

エクスプローラ・フォルダの詳細表示ような画面が欲しくなって、リスト表示も。
後付け、後付けで機能を付け足すから、時間を無駄に食う。
fileman01

あとは、使い回せるように、モジュール化しないといけない。
自分でこういうコードを書いてて思うんですが、Wordpressって、ホントに良くできたシステムですよねぇ。

packer(.NET版)を勝手に改造

これ、すごい。こんなスマートなビルの壊し方があるんすね。。。ビル爆破より地味だけど、なんかお金かかりそう。
http://www.bbc.co.uk/news/world-asia-21406927

それはともかく。

javascriptコードを圧縮するのに packer (http://dean.edwards.name/download/#packer) の.NET版をよく使っています。
が、.NET版は(たぶん)メンテされておらず?ソースコードも .NET Framework 1.0時代のものなので、見栄えがかなり悪いし、テキストボックスの入力が32KBに制限されていたり、とちょいと不満がくすぶっていました。
最近Javascriptコードを書くことが多くなって、頻繁に使い出すと、どうもこのUI自体が(僕にとっては)使いにくい。

で、あまり見た目を触らずボタン類の配置、ビジュアルスタイルの適用などを含めて改造。
自分用の書庫の意味もかねているので、ここにアップロード。

左がオリジナル。右がUI改造版
jspacker myjspacker

改造点は、

  • ボタン配置・レイアウトを変更した。
  • ビジュアルスタイルを適用するようにした。
  • ラベルを日本語化した。.configファイルでラベル編集可能。
  • テキストボックスの32KB制限を外した。
  • ファイルからの読込(Loadボタン)時に文字コードを判別するようにした。
    (文字判定にInternet Explorerのモジュールを使っているのでIEを削除している方(いないと思うけど)の環境では文字判定できません

ユーザーインターフェイスの部分(Visual C#のIDE上で編集できる部分)のみ修正したのでpacker本体のアルゴリズムには一切タッチせず。packer自体のバージョンは上がっていると思うので、たぶん古いアルゴリズムのままのはず。分からんけど。

プロジェクトのプラットフォームを.NET Framework 3.5にして、フォームを定義しているソースファイルでIDE機能のデザイナーで編集される部分のコードを分離( partial class化)してます。

<< Download from here if you need.>> もし必要ならダウンロードはこちら
(改造後のVisual C# 2008のプロジェクトソースも同梱してます。)
(なんか、chromeだと、危険だ!とか出てダウンロードできませんが、別になんも仕込んではいないです。)

使い方は・・・説明しなくても・・・(^^;;;
ラベルを英語にしたい場合は、Javascript packer.exe.config ファイルを開いて、

&lt;setting name=&quot;Lang&quot; serializeAs=&quot;String&quot;&gt;
&lt;value&gt;ja&lt;/value&gt;
&lt;/setting&gt;

の中の、ja の部分を ja以外、たとえば、en とかにしてください。
ラベルを修正したい場合は、configファイルの該当箇所を修正してください。ただ、ボタン幅は固定なので長さによってははみ出るかも?

でわでわ。

iPad debut

アップル信者ではありません、僕は。

2年前 iPad 出たとき、こんなの使わねー、とか思ってました。・・・が、アンドロイドOSのあまりの使いにくさ、わかりにくさに辟易してたのもあって、とうとう手に入れてしまいました。

初代iPad/iPad2の唯一の不満点が、画面解像度。それも新iPadで解決。FullHDサイズの画像・動画が縮小しないで表示・再生できる、という点に惹かれて衝動買いです(^^)

クアッドコアグラフィックでサクサク、表示性能が段違いにいいっすね~。

という、iPad購入ブログ記事がこの日あちこちで上がっているに違いない(^-^;