You can do this in many ways. One obvious way is to just wrap
this in a function:
sub database_handle {
my $dbh = DBI->connect("DBI:Sybase:CRAP", "sa", "");
die "connect failed: $DBI::errstr" unless $dbh;
$dbh;
}
Then get a new database handle using
my $dbh = database_handle();
Is this what you wanted? Or did you want to save the handle
somehow, and return the already-open connection if it's
open already? You could do that like this:
{
my $dbh;
sub database_handle {
return $dbh if defined $dbh;
$dbh = DBI->connect("DBI:Sybase:CRAP", "sa", "");
die "connect failed: $DBI::errstr" unless $dbh;
$dbh;
}
}
And you'd get access to the handle the same way, by calling
database_handle. This will return an already-open connection.
Or you could get trickier and wrap this in an object wrapper
around DBI. This is something I like to do, because I like to
write code that works on different databases, so I provide
one main class that wraps around DBI, then subclass that to
provide database-specific functionality (stuff that differs
between DBD drivers, etc.).
Here's a simple class:
package My::DB;
use strict;
sub new {
my $class = shift;
$dbh = DBI->connect("DBI:Sybase:CRAP", "sa", "");
die "connect failed: $DBI::errstr" unless $dbh;
bless { handle => $dbh }, $class;
}
sub handle { $_[0]->{handle} }
You could use this like this:
my $dbh = My::DB->new->handle;
This may seem relatively useless (why I am returning an object
containing only an open database handle? why not just
return the handle itself?), but the way I use this is, I don't
actually use any of the DBI methods directly in my main code.
I have wrappers
around DBI methods that do a bit more, like do some automatic
exception handling, bind variable processing, etc.
For example, I have an execute method that does this:
sub _execute {
my $self = shift;
my($sql, $place, $finish) = @_;
my($sth, $rv);
eval {
$sth = $self->prepare($sql);
$rv = $sth->execute(ref $place eq "ARRAY" ? @$place : ());
$sth->finish if $finish;
};
if ($@) {
My::Exception::DB->throw(sql => $sql, error => $@);
}
return $finish ? $rv : $sth;
}
And my prepare method uses prepare_cached, instead of
just plain prepare. And so on.