Entries

perl+DBI プログラムの鉄則 - fetchrow_arrayref を使え

perl+DBI プログラムの鉄則 のつつき。

鉄則その3.

   while ( my $arr_ref = $sth->fetchrow_arrayref ){
      my ($hoge, $fuga) = @$arr_ref;
      ...
   }

SELECT 時は上記のように fetchrow_arrayref を使うこと。そして必ずスカラーに
代入すること。せっかく fetchrow_arrayref を使っていても

   while ( my $arr_ref = $sth->fetchrow_arrayref ){
      print "$$arr_ref[0] $$arr_ref[1]\n";
   }

などと書いては台無しである。配列のインデックスで指定すると取得カラムの
増減に非常に弱い。そしてなりより、$$arr_ref[1] が何を意味するのか
さっぱりわからない。


fetchrow_array は使わない。複数カラムを取得する場合は問題ないが、
1カラムのみ取得する際に

   $sql = "SELECT hoge FROM table1";
   $sth->prapre($sql);
   $sth->execute;
   while ( $hoge = $sth->fetchrow_array ){
      ...
   }

とスカラーコンテキストで fetchrow_array を使ってしまうと問題が
出てくる。もしこのとき hoge が NULL であった場合、fetch 途中にも
かかわらずループが終了してしまうから。

fetchrow_hashref は使わない。

   while ( my $hash_ref = $sth->fetchrow_hashref ){
      print "hoge=[$hash_ref->{hoge}] fuga=[$hash_ref-{fuga}]\n";
   }

と書けるのは便利ではあるが、ハッシュはタイプミス耐性がない。

   print $hash_ref->{hoge};



   print $hash_ref->{moge};

とタイプミスした場合、値は undef になる。しかし DB 内の NULL は、DBI に
おいては undef として扱われるため、タイプミスと NULL の区別がつかない
(exists で調べれば区別はつくが、そんなことをわざわざやる人はほとんど
いない)。

fetchall 系は、最初は教えない。数百万・数千万・数億レコードの相手を
するようになったときに困るから。最終的にオンメモリに置くデータなら
別にかまわないが、それはメモリサイズを直感的に把握できるようになってから。


fetch というメソッドもあるが、これは fetchrow_arrayref の別名となっている。
fetch という短くてタイプしやすいメソッド名の権利を獲得したのは
fetchrow_array でもなく、fetchrow_hashref でもなく、fetchrow_arrayref
なのである。

これこそまさに fetchrow_arrayref を使うべし、という DBI 製作者のメッセージ
ではなかろうか (知らんけど)。
このエントリーをブックマークに追加 ブックマークに追加する
この記事に対してトラックバックを送信する(FC2ブログユーザー)
http://68user.blog27.fc2.com/tb.php/6-3d1ceb64

0件のトラックバック

4件のコメント

[C52] typo?

参考にさせていただいております。で、何回か見ているうちに気づいたのですが。
最後の一節、fetchは
fetchall_arrayref じゃなくてfetchrow_arrayref のaliasじゃなかったでしたっけ。
  • 2006-12-21
  • もぎゃ
  • URL
  • 編集

[C53]

typo でした。fetchall_arrayref -> fetchrow_arrayref に修正いたしました。ご指摘ありがとうございました。
  • 2006-12-27
  • 68user
  • URL
  • 編集

[C72]

大変勉強させていただきました。
my ($hoge, $fuga) = @arr_ref;
ではなくて
my ($hoge, $fuga) = @$arr_ref;
でしょうか。
  • 2007-04-23
  • gama子
  • URL
  • 編集

[C205]

ご指摘ありがとうございます。いまさらですが修正いたしました。
  • 2008-02-22
  • 68user
  • URL
  • 編集

コメントの投稿

投稿フォーム
投稿した内容は管理者にだけ閲覧出来ます

Appendix

プロフィール

Author:68user
http://X68000.q-e-d.net/~68user/

ブロとも申請フォーム

この人とブロともになる

ブログ内検索

Powered By FC2ブログ

Powered By FC2ブログ
ブログやるならFC2ブログ