You're declaring two variables named $dbh
. Use $dbh
instead of my $dbh
to use an existing variable.
Also, you don't actually try to connect at compile-time as you want to do, and you forgot to check if prepare
succeeded. Fixed:
use constant {
MY_HOST => 'database=MYDB;host=MYHOST',
MY_USER => 'USER',
MY_PASS => 'PASSWORD',
};
{
my $dbh;
sub get_db_handle {
$dbh ||= DBI->connect(
'DBI:mysql:' . MY_HOST,
MY_USER, MY_PASS,
{ PrintError => 0, AutoCommit => 0 },
)
or die $DBI::errstr;
return $dbh;
}
}
# Make sure DB errors are discovered early.
BEGIN { get_db_handle(); }
...
my $dbh = get_db_handle();
my $sth = $dbh->prepare($sql)
or die $DBI::errstr;
If you use RaiseError => 1
, this can be shortened to
use constant {
MY_HOST => 'database=MYDB;host=MYHOST',
MY_USER => 'USER',
MY_PASS => 'PASSWORD',
};
{
my $dbh;
sub get_db_handle {
return $dbh ||= DBI->connect(
'DBI:mysql:' . MY_HOST,
MY_USER, MY_PASS,
{ RaiseError => 1, PrintError => 0, AutoCommit => 0 },
);
}
}
# Make sure DB errors are discovered early.
BEGIN { get_db_handle(); }
...
my $dbh = get_db_handle();
my $sth = $dbh->prepare($sql);
Not sure how much sense it makes to cache a handle that has transactions enabled, though.