SQL::Abstractでお手軽DB操作

DBにPerlDBIモジュールを使ってInsertするときは、下記のようにしてました。

テーブル名はTableName,カラム名はhoge1,hoge2,hoge3とした場合

my $dbcon = DBI->connect(....);
my $dbInsert = $dbcon->prepare(q/insert into TableName (hoge1,hoge2,hoge3) values (?,?,?) /);
my $dbResult = $dbInsert->execute($hoge1,$hoge2,$hoge3....);

ただ、このようなバインドする変数を書いていく方法だと、カラムの数が多くなると、実装中に書いていくのが面倒になる。
カラム名に対応したデータを1:1でDBに入れたいだけなのに、、、ということで、ハッシュでやれるといいなぁと思って調べてみた。


ハッシュを使って、キーにカラム名、データにInsert/Updateしたいデータを入れて、そのハッシュをそのままSQLにしてしまえるもの。Perlのモジュールで、SQL::Abstractというものがありましたよ。

使い方はいたって簡単。insertメソッドの引数にテーブル名とハッシュリファレンスを指定するだけ。
上記の例を変更するとこんな感じ。

my %datahash = ("hoge1" => 'aaaaaaaa', "hoge2" => 'bbbbbbbb');

my $dbcon = DBI->connect(....);

my $sql = SQL::Abstract->new;
my ($stmt,@bind) = $sql->insert('TableName',\%datahash);

my $dbInsert = $dbcon->prepare($stmt);
my $dbResult = $dbInsert->execute(@bind);

つまり、$sql->insertで自動的にSQL文が生成され、SQL文自体が$stmtにセットされ、それに合わせて入れるデータの配列が@bindにセットされます。
従って、それらをprepare,executeすればOK.

Formの各項目のNameの値をDBのカラム名にして、POSTデータをハッシュで受けとって管理すれば、あとはそのハッシュをそのままSQL::Abstractに入れてあげれば、お手軽にDB登録が実装できます。
CGIモジュールを使ってれば、Vars()メソッドを使えば、POST/GETで受け取ったデータがハッシュに入ります。

 my %hash = $cgi->Vars();

もし不要なハッシュデータがあれば、PerlならDelete関数を使ってハッシュの値を削除すればOK.


ただ、current_timestampなど、SQLの機能を使って現在日時をinsertする場合は対応できないみたい。

my %datahash = ("hoge1" => 'current_timestamp');

とかやってみたけどエラーが出た。

current_timestampなどのSQL側の機能をそのまま使う場合は、ハッシュのキーにDBのカラム名、データにスカラーリファレンスを指定すればできました。情報ありがとうございました > tomyheroさん

my %datahash = ("hoge1" => \'current_timestamp');

SQL::Abstractは、selectやdeleteにも対応しているので、SQL文をできる限り書きたくない人にはいいかも。ただ、selectはcountが使えないみたい。とりあえずは、selectはSQL文を直書きの方がしっくりくるので、update/insert/deleteにこのモジュールを使っていこうかと思います。