Class::DBIで複数カラムの主キーがjoinできない

IDとバージョンを外部キーにするOracleデータベースの検索をする必要があって、色々といじった。

SELECT a.name FROM a , b WHERE a.id = b.id AND a.version = b.version

まず、複数のキーを主キーにしている場合にIDというカラムがあるとエラーが出る。これよくわからん。

続いて、Class::DBI::Viewで扱おうとしたが、参照しかできないユーザー使っているので、テンポラリのテーブルが作れず。試しに普通の権限で実行してみたが、これも同じエラーが出て駄目。オラクルが悪いのか?

TemporaryTableが駄目なのか?と思い、use Class::DBI::View qw(SubQuery);でやってみたけど、どう書いたらいいのかよくわからん。

sub setup_view { my($class, $sql) = @_; $class->table("($sql)"); # Sweet }

ってなっているから、副問い合わせだけ書けばいいんダヨナァなんて悩むも、よく考えたら

副問い合わせで複数カラムって駄目ジャン

結局set_sqlで普通にSQL文書いた。

オラ狂ぅ

DBD::CSVとDBD::AnyData

創薬系で使っているソフトで古いタイプはCSVで出力するものが結構多いので、CSVをDBIで扱うためのモジュールDBD::CSVDBD::AnyData を触ってみた。DBD::CSVはCSVをSQL::Statementで扱えるようにするモジュールで、DBD::AnyDataはもう少し広くXMLとか/etc/passwdとかのほかのフォーマットも扱えるらしい。

サンプルとして以下のカンマ区切りのファイルを用意する。ちなみにヨコゼキ義侠の慶が入荷したらしい。あー飲んでみたい。

Name,Category,Loc,Vol 群馬泉,純米,群馬,1800 義侠,純米,愛知,720 飛露喜,純米,福島,720 國香,吟醸,静岡,1800 喜久酔,純米,静岡,720

ポイントは両方とも$dbhでテーブル名とカラム名を与えること。区切り文字とか改行文字も指定する。カラム名を明示的に指定しないといわゆるヘッダーがカラム名となる(DBD::CSV,DBD::AnyDataともに)

そこまでやれば、普通にSQLを実行だ。

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

my $dbh = DBI->connect("DBI:CSV:csv_eol=\n;csv_sep_char=,");
$dbh->{'csv_tables'}->{'out'} = {
                                'file' => 'sample_j.csv',
                               };
my $sth = $dbh->prepare(q/SELECT * FROM out where Category = '純米'/);

$sth->execute();

while(my $t = $sth->fetchrow_arrayref){
print join(":",@$t),"\n";
}

$sth->finish;
$dbh->disconnect;

上の例はアレイのリファレンスだが、ハッシュのリファレンスも可能。その場合はヘッダ名でアクセスできる。

#!/usr/bin/perl

use strict;
use warnings;
use DBI;

my $dbh = DBI->connect('dbi:AnyData:');

$dbh->func('test','CSV','sample_j.csv','ad_catalog');

my $sth = $dbh->prepare(q/select * from test where Category = '純米'/);

$sth->execute()
 or die "execute: " . $dbh->errorstr();

while(my $t = $sth->fetchrow_hashref){
 print $t->{Name},":",$t->{Loc},"\n";
}

$sth->finish;
$dbh->disconnect;

DBD::AnyData(Version: 0.08)では実行すると以下のエラーが出てちょっと気持ち悪い。


Service description 'file:' can't be loaded: 404 File `' does not exist

DBD::CSVとDBD::AnyDataどっち使うかは$dbhをどう指定するかの部分だけの好みなんだろうけど、CSV扱うという部分に関してはDBD::CSVのほうがわかりやすくて好き。もう少し複雑な書式のデータはDBD::AnyDataのほうがいいのかもしれないが、DBD::AnyDataの/etc/passwdのサンプルぐらいしか試してないので、本当のところはわからん。

DBD::CSVもClass::DBIで扱えるらしい(ナイス!)

O/Rマッピング最高!

CatalystWEB+DB PRESS特別総集編見てClass::DBIに(やっと?)目覚めたワタクシですが、自分でコードを書いてみてその素晴らしさに感激。

なにがすごいかって、スンゲーシンプルになるのが気持ちいい。コレとかやっとわかってきた。わかるとキモチイイし、コード書くのが更に面白くなるネ。

ClassDBIのWIKIなどみてガシガシ書いておりますヨ。