DBI 自身の TRACE
あけましておめでとうございます。
新年も RT にあがっているパッチをあてながら DBIx::Simple 1.26 を使っています*1。
以前から書いてるとおり DBIx::Simple + SQL::Abstract は小粋ですばらしいんですが,吐いた SQL 文を調べる機能がありません。どうせ DBI 自体にトレース機能あるんじゃね?と思ってドキュメントを見たら,やっぱりありました。
my $db = DBIx::Simple->connect( ... ); $db->dbh->trace(1); #$db->dbh->trace(1, 'sql.log'); # ログファイルを指定する場合
出力先としては STDOUT, STDERR か何らかのファイル名を指定することしかできないのでロガー等を通して出すことができません。あくまで困ったときの知恵ということで。
ちなみにログレベル 1*2の出力例は,
DBI::db=HASH(0x9e53990) trace level set to 0x0/1 (DBI @ 0x0/0) in DBI 1.53-ithread (pid 5275) <- prepare('DELETE FROM items')= DBI::st=HASH(0x9e53ae0) at Simple.pm line 141 <- execute= '0E0' at Simple.pm line 160 <- finish= 1 at Simple.pm line 256 <- prepare('INSERT INTO items (handle, id, name, short_name) VALUES (?, ?, ?, ?)') = DBI::st=HASH(0xa5f6b0c) at Simple.pm line 141 <- execute('180' '1' ...)= 1 at Simple.pm line 160 <- finish= 1 at Simple.pm line 256 <- execute('180' '2' ...)= 1 at Simple.pm line 160 <- finish= 1 at Simple.pm line 256 <- execute('180' '3' ...)= 1 at Simple.pm line 160 <- finish= 1 at Simple.pm line 256
こんな出力が大量に出て焦ります。「...」で省略されている部分は「$DBI::neat_maxlen」をいじると省略させずに出すこともできます。
なお INSERT してる部分のコードは,
foreach my $line (@data) { my @cells = split ',', $line; my %rec = map { $_ => (shift @cells) } @fields; $db->insert('items', \%rec); }
こーんな感じの適当なコード(つまりいちいち prepare せずに毎度毎度レコード用構造体を作っている)なんですが,同じフィールド群への INSERT だと自動的に prepare したものを再利用してくれるところが DBIx::Simple のやはり小粋なところですね*3。