こんばんはこんばんは。 今週末は「Perl のお祭り」こと YAPC::Asiaですね!皆様、見る方も発表する方も準備は万全でしょうか?

(私?お察しください。。。資料はちょっとずつ書いてるよ!)

ここで宣伝。Perl と SQL のいろいろ というタイトルでお話させていただきます。裏番組がどちらも大変なビッグネームなので恐縮なのですが、初中級者くらい向けに Perl と SQL にまつわる話を させていただこうと思っております。

(※ここまでテンプレ)

Kappa という ORM の話。今日は select にまつわる色々です。

目次

事前準備

テーブルを作っておきましょう。前回作ってれば作らなくていいです。

use DBI;
my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile",'','');
$dbh->do("
CREATE TABLE detective (
  id    INT PRIMARY KEY,
  name  TEXT
);
");

データも入れといてくださいね。(これも前回入れてる人は入れなくていいです。)

use Kappa;
my $db = Kappa->new($dbh);
$db->insert('detective', { id => 1, name => 'シャーロック・シェリンフォード' });
$db->insert('detective', { id => 2, name => '譲崎 ネロ' });
$db->insert('detective', { id => 3, name => 'エルキュール・バートン' });
$db->insert('detective', { id => 4, name => 'コーデリア・グラウカ' });

select 系のいろいろ

select 系は、メソッドがいっぱいありますが、一定のルールになっているので、慣れれば分かるようになると思います。基本的には、4タイプの戻り値指定と、4タイプの select 方法の組み合わせです。

戻り値指定の4タイプ

  • select
  • select_row
  • select_all
  • select_itr

戻り値指定は上記の4種があります。

select はコンテキストに応じて 1レコード or 全レコードを返します。

my $row  = $db->select('detective', { id => 1 }); #この場合だと 1レコード
my @rows = $db->select('detective', { });         #この場合だと全レコード

で、select_row系 は、この1レコードを返すタイプです。前回もちょっとだけ説明しましたが、1レコード分の値は row_object_enable が TRUE なら Row オブジェクトが返り、FALSE なら hashref(fetchrow_hashref の値)が返ります。

$row = $db->select('detective',     { id => 1 }); 
$row = $db->select_row('detective', { id => 1 }); #この2つは同じ

select_all系 は全レコードを返すタイプです。配列が返り、配列の1要素は、row の場合と同じです。(row_object_enable に応じて変わります。)

@rows = $db->select('detective',     { });
@rows = $db->select_all('detective', { }); #この2つは同じ

select_itr系 はイテレータを返します。イテレータは next() ってメソッドだけが使えます。next を呼ぶと、1行分データ(Row オブジェクト or hashref)が 返ります。

my $itr = $db->select_itr('detective',     { });
while ( my $row = $itr->next() ) {
   # $row をつかってあんなことやこんなことをします。
}

select 方法の4タイプ

  • select
  • select_*_with_fields
  • select_*_by_sql
  • select_*_named

一番シンプルな select はとくに説明しなくても分かるかと思います。テーブル名と条件を指定します。

with_fields は select と似てますが、引数に select 対象のカラムを指定できます。たとえば、select_row_with_fields だと こんな感じです。

my $row = $db->select_with_fields('detective', ['id'], { id => 1 }); # id だけ取る

この例だと、id だけ取るので、name は取れません。ビューとかに select する場合にハイコストな計算が走る行を除外したい時とかに 使うと良いと思います。

by_sql は、テーブル名ではなく、SQL を指定します。プレースホルダを使います。

my @rows = $db->select_all_by_sql('SELECT * FROM detective WHERE id = ?', [1]);

第2引数は配列ではなく、配列リファレンスで bind する値を指定します。(配列ではなく、配列リファレンスなのは、第3引数としてテーブル名を指定したい ためです。テーブル名は Row オブジェクトの紐付けに使うので重要です。)

named なやつは、by_sql に似ていますが、名前つきプレースホルダが使えます。(これもテーブル名ではなく、SQL を指定するタイプです)

my $row = $db->select_row_by_sql('SELECT * FROM detective WHERE id = :id', { id => 1 } );

何となくわかったでしょうか?

たとえば select_itr_named なら、「イテレータを返して、名前つきプレースホルダの SQL を使うやつ」です。select_all_by_sql なら、「配列を返して、(名前なしの)プレースホルダの SQL を使うやつ」です。select_row_with_fields なら、「1行を返して、指定したテーブルの、指定したフィールドを返すやつ」です。

まとめ

今回は select 系のメソッドを紹介してみました。探偵さんの名前は覚えましたか?これは重要なファクターですよ! (このネタ、どこまでどの程度通じてるのかよく分かりませんが、マイブームなので続けますよ!)

次回は Row オブジェクトを紹介しようかなー。