2011年11月02日

2011年11月02日

 MySQL で書いていたウェブアプリを SQLite に移植中。アプリの動作自体には特に不満はないのだが、小規模なアプリなので、データベースがファイルで扱える SQLite の方がメンテナンス性がいいかなと思った。Perl で書いているので DBD::MySQL から DBD::SQLite に移行するのだが、細かい仕様がけっこう違っていてわりと苦労した。DBD::MySQL ではこのコードが通るのだが:

$sth = $dbh->prepare("SELECT * FROM groups"); $result = $sth->execute; if ($result) { for ($i = 0; $i < $result; $i++) { $a = [@{$sth->fetchrow_arrayref}]; push @groups, $a; } } else { $error = "SELECT failed: " . $sth->errstr; }

 DBD::SQLite では動かない。上のコードは $sth->execute がレコードの数を返すことを前提としているが、「SELECT 文の場合、execute はレコードの数を返さない」と DBI のドキュメントには明記されているので、動かないのが仕様。こんな風に修正している。

$sth = $dbh->prepare("SELECT * FROM groups"); $result = $sth->execute; if ($result) { while ($a = $sth->fetchrow_arrayref) { $a = [@{$a}]; # Copy the array content push @groups, $a; } } else { $error = "SELECT failed: " . $sth->errstr; }

 INSERT 文で複数レコードを一度に挿入できない、という違いもあった。このため、mysqldump で作った SQL 文をそのまま sqlite3 に食わせてもうまくいかず、1レコードごとに分けないといけない。データベースのプログラミングは慣れてないので、いろいろと大変だな。

タグ:
Posted at 2011年11月02日 00:57:20
email.png