DBI使うときの鉄板

  • RaiseErrorを有効にしてDBIにdieさせてevalでキャッチ。
  • AutoCommitは切る。SELECT文だけしか使わない時はどっちでもいい。
  • 問題なく全てが終了したときだけcommitする。他は全部rollbackして元に戻す。
  • 外部から入力された値をSQL文に組み込むときは必ずプレースホルダを使う。
  • SELECT文を使うならなるべくbind_columnsとfetchの組み合わせで値を取得するようにする。
use DBI;

# SQL文。
my $sql = <<SQL;
SELECT *
FROM SampleTable
WHERE ID = ?
SQL

my $dbh = DBI->connect('DBI:mysql:SampleDB:localhost:3306',
                       'username',
                       'password',
                       {'RaiseError' => 1, 'AutoCommit' => 0});
if( !$dbh ){
    # データベースハンドルの取得に失敗したときの処理。
}
my($id, $val1, $val2);
eval{
    my $sth = $dbh->prepare($sql);
    $sth->execute(134);
    $sth->bind_columns(undef, \($id, $val1, $val2));
};
if($@){
    $dbh->rollback();
    $dbh->disconnect();
    # エラー処理
}

while($sth->fetch()){
    print "$id / $val1 / $val2\n";
}

$dbh->commit();
$dbh->disconnect();