有条件地连接到数据库

3

我一直在使用DBI模块连接数据库时遇到了一些问题。我有一个属性文件,其中指定了是否要通过简单的database=oracledatabase=postgres连接我的Oracle或Postgres数据库。我的属性文件是使用Config::Tiny模块设置的,我的变量设置如下:

my $database = $config->{myDB}->{database};
                       ...

我不理解的是,尽管这对我所有的变量都起作用,但如果我尝试像这样连接到属性文件中指定的任何数据库...
if($database eq "oracle"){
    my $dbh = DBI->connect("dbi:Oracle:host=abc123-server;sid=XE;port=1521","User","Pass");
}
elsif($database eq "postgres"){
    my $dbh = DBI->connect("dbi:Pg:dbname=pepperoni;host=789xyz-server;port=5444;","Foo","Bar");
}else{
    print "Could not connect to a database";
}

当我运行程序时,出现了以下错误:

Global symbol "$dbh" requires explicit package name at supportvuloop.pl line 70.
Global symbol "$dbh" requires explicit package name at reportloop.pl line 80.
Global symbol "$dbh" requires explicit package name at reportloop.pl line 81.
Global symbol "$dbh" requires explicit package name at reportloop.pl line 82.
Global symbol "$dbh" requires explicit package name at reportloop.pl line 88.

如果它们不是if条件的一部分,我可以很好地连接到任何一个数据库,为什么现在会导致错误?


为什么不直接将整个“Oracle:host=abc123-server;sid=XE;port=1521”字符串放入配置文件中呢?这样,您就可以在不更改代码的情况下使用任何数据库。为了方便切换,将Oracle和Postgres两行都放入配置文件中,并注释掉您不使用的那一行。 - cjm
@cjm - 说到这个,可以有一个Oracle或Sybase文件,并通过读取不同的配置文件名来切换。 - DVK
2个回答

4

您的$dbh变量没有在正确的范围内声明。 您应该在“if”语句之前声明它:

my $dbh;

if ($x) {
    $dbh=xxx1;
} elsif ($y) {
    $dbh=xxx2;
} else { # error
}
...

你的代码结构如下,$dbh变量在"if"块中声明为my(并且也在"else"块中独立地声明),因此你的代码其余部分没有看到这些变量。

更多阅读资料:


3
DVK已经回答了你的问题,但我想给出一个提示。我会按照以下方式编写代码,因为它将配置与数据库连接分离:
my %connect_info = (
   "oracle" => {
      dsn      => "dbi:Oracle:host=abc123-server;sid=XE;port=1521",
      user     => "User",
      password => "Pass",
   },
   "postgres" => {
      dsn      => "dbi:Pg:dbname=pepperoni;host=789xyz-server;port=5444;",
      user     => "Foo",
      password => "Bar",
   },
);

my $connect_info = $connect_info{$database}
   or die("Unknown database $database\n");

my $dbh = DBI->connect(
   $connect_info{dsn},
   $connect_info{user},
   $connect_info{password},
);

+1 - 我不想在我的回答中混淆代码样式,但像这样分解是一个很好的想法。 - DVK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接