- 2009/12/30 Wed
-
以前書いたモジュールの AutoCommit を手当たり次第に切っていったら自動テストの出力にIssuing rollback() for database handle being DESTROY'd without explicit disconnect().
とかいうのが混じるようになって ちょと調べたのでメモ。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; $dbh->do('update foo set bar=1'); $dbh->commit; $dbh->disconnect;
まず普通に。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; $dbh->do('update foo set bar=1'); $dbh->commit; #$dbh->disconnect;
disconnectを省略しても変化なし。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; $dbh->do('update foo set bar=1'); #$dbh->commit; $dbh->disconnect;
commitを省略。警告はでない。当然、コミットもされない。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; $dbh->do('update foo set bar=1'); #$dbh->commit; #$dbh->disconnect;
両方省略したところで件の警告。
モジュールを眺めたら、select の後の条件分岐で disconnect せずに抜けてる箇所があった。
disconnect の漏れはともかくとして、select でも commit/rollback が必要なものなのか。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; my $sth = $dbh->prepare('select * from foo'); $sth->execute; undef $sth; #$dbh->commit; #$dbh->disconnect;
これだと警告。SQLiteのデータ型がフリーダム過ぎる。use DBI; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->{AutoCommit} = 0; my $sth = $dbh->prepare('select * from foo'); $sth->execute; undef $sth; $dbh->commit; #$dbh->disconnect;
警告でない。rollback でも同様。use strict; use warnings; use DBI; unlink 'foo.db'; my $dbh = DBI->connect('dbi:SQLite:dbname=foo.db'); $dbh->do('CREATE TABLE foo(foo, bar INTEGER, baz TEXT, qux NULL)'); $dbh->do('INSERT INTO foo VALUES(1,1,1,1)'); $dbh->do("INSERT INTO foo VALUES('2','2','2','2')"); $dbh->do("INSERT INTO foo VALUES('a','a','a','a')"); foreach my $col('foo','bar','baz','qux') { foreach my $val("1","'1'","2","'2'","'a'") { my $sth = $dbh->prepare("SELECT * FROM foo WHERE $col=$val"); $sth->execute; $sth->fetch or warn "$col=$val"; $sth = $dbh->prepare("SELECT * FROM foo WHERE $col=?"); $sth->execute(eval $val); $sth->fetch or warn "$col=? $val"; } }
> perl datatype.pl foo=? 1 at datatype.pl line 23. foo='1' at datatype.pl line 19. foo=? '1' at datatype.pl line 23. foo=2 at datatype.pl line 19. qux=? 1 at datatype.pl line 23. qux='1' at datatype.pl line 19. qux=? '1' at datatype.pl line 23. qux=2 at datatype.pl line 19.
(型省略) INTEGER TEXT NULL 1->1(*1) ○/×(*2) ○/○ ○/○ ○/× 1->'1' ×/× ○/○ ○/○ ×/× '2'->2 ×/○ ○/○ ○/○ ×/○ '2'->'2' ○/○ ○/○ ○/○ ○/○ 'a'->'a' ○/○ ○/○ ○/○ ○/○
*1)更新時の指定->参照時の指定
*2)ベタ展開/プレースホルダ「スリッパ野郎!」
とか罵られつつ、スリッパを買いにぶらりと出かける。
なんというかこう、見るからにあったかそうなスリッパを買ってきました。
これで今年の冬を戦い抜ける…!
あと、フライパンの蓋を買ってきたりとか。
箸を買ってきたりとか。
イーモバイル端末を買い増ししてきたりとか。Pocket WiFi (D25HW) イー・モバイル
http://emobile.jp/products/hw/d25hw/
うん。
結局、我慢できなかったんだ。
ウィルコムとイーモバイルとイーモバイルとドコモ。
これでようやく、ウィルコムを解約する踏ん切りもついたよ!(遅すぎる)
今までありがとう、AH-N401C。