Database 数据库连接脚本在4次成功连接后崩溃

Database 数据库连接脚本在4次成功连接后崩溃,database,perl,dbi,Database,Perl,Dbi,我需要查询一组SAP sybase数据库以获取一些信息,并将其打印为逗号分隔的列表。所以我想我写了一个perl脚本,通过DBI模块连接到这些数据库中的任何一个。这是我想到的 my $user = "someuser"; my $passwd = "somepassword"; my @sids=(filled with DB identifiers); my $output=""; my $size; my $version; my $id; my $dsn; my $dbh; my $sid;

我需要查询一组SAP sybase数据库以获取一些信息,并将其打印为逗号分隔的列表。所以我想我写了一个perl脚本,通过DBI模块连接到这些数据库中的任何一个。这是我想到的

my $user = "someuser";
my $passwd = "somepassword";
my @sids=(filled with DB identifiers);
my $output="";
my $size;
my $version;
my $id;
my $dsn;
my $dbh;
my $sid;
my @row;
my $sth1;
my $sth2;
foreach $sid (@sids) {
        print $sid."\n";
        $dsn = "dbi:Sybase:server=$sid;charset=iso_1;tdsLevel=CS_TDS_50";
        print $dsn."\n";
        $dbh = DBI->connect($dsn, $user, $passwd,{ PrintError => 0,RaiseError => 0, AutoCommit => 1, syb_enable_utf8 => 1});
        print "DBI OK\n" if defined ($dbh);
        $sth1 = $dbh->prepare('select SUM(size) from master..sysusages WHERE dbid = 4 AND segmap = 3');
        $sth2 = $dbh->prepare('select @@version');
        $sth1->execute;
        while (@row = $sth1->fetchrow) {
                $size = $row[0];
        }
        $size = $size * 16 / 1024;
        $sth1->finish;
        $sth2->execute;
        while (@row = $sth2->fetchrow) {
                $version = $row[0];
        }
        $sth2->finish;
        $output = $sid.",".$size.",".$version;
        $dbh->disconnect;
        print $output."\n";
}
当我执行此操作时,它在第4次迭代后崩溃,因为没有设置连接句柄。因此,第五个DB的连接不再工作

Can't call method "prepare" on an undefined value at ./check_sybasedbs.pl line 36.
第36行是报表1的编制


我试着把睡眠命令放在不同的位置。我还试图通过
undef
显式清理重用的变量。现在我没有主意了,非常感谢您的输入。

您的代码可以作为下面的示例编写(请参见
如果……否则…
块中的
$dbh

注意:
严格使用;使用警告有助于避免许多陷阱,
使用诊断有助于在困难情况下识别问题


注意:
$sth->fetchrow\u hashref
允许按名称计算地址散列元素,无需计算数组的索引,就像
$sth->fetch\u rowarray
在我的naiv中,我认为我隐藏了一些代码行,我确信这些代码行可能不是这种错误行为的原因。事实证明,的确如此。因此,我的问题的原因是一个简单的逻辑错误,导致连接到某个数据库后使用的密码错误

连接到数据库时,将
PrintError
RaiseError
更改为
1
,并打印/检查错误消息。DBI connect('server=;charset=iso_1;tdsLevel=CS_TDS_50','user',…)失败:服务器消息编号=4002严重性=14状态=1行=0服务器=sid文本=登录失败。OpenClient消息:LAYER=(4)ORIGIN=(1)SEVERITY=(4)NUMBER=(44)顺便说一句,当我混淆数据库连接到@dgwWell的顺序时,结果是一样的,现在您找到了罪魁祸首。。。尝试找出无法连接到该特定服务器的原因。这不再是perl脚本的问题了。提示:不要将变量设置为“全局”变量!声明它们的全部目的是将它们的范围限制在需要它们的地方,通过将所有声明放在顶部,您颠覆了这个过程!Re“当我在循环中声明它们时,它们的作用域是否仅限于循环的一次迭代?”。这是可取的。现在,您正在重用变量,并让它们从使用它们的循环中泄漏出来。对于我的$sid(@sids){my$dsn=''.';my$dbh='.;…},您应该有
谢谢您的输入。我认为这是一种跳过不起作用的连接的好方法,但是脚本会因为dbi连接失败而崩溃anyway@laghorn--至少在这种情况下,您会被告知无法连接到哪个数据库。然后调查可能存在的潜在问题。
use strict;
use warnings;
use feature 'say';

use DBI;

my($user, $passwd)  = qw/someuser somepassword/;
my @sids            = qw/server1 server2 ... server#/;

foreach my $sid (@sids) {
        my $dsn = "dbi:Sybase:server=$sid;charset=iso_1;tdsLevel=CS_TDS_50";

        say "DSN: $dsn";

        my $dbh = DBI->connect($dsn, $user, $passwd, {  PrintError => 1,
                                                        RaiseError => 1,
                                                        AutoCommit => 1,
                                                        syb_enable_utf8 => 1
                                                    }
                                );

        if( not defined ($dbh) ) {
            say "WARNING: Could not connect to $dsn";
        } else {
            say "INFO: DB connection established";

            my($size,$version);

            my $query = 'SELECT
                            SUM(size)
                         FROM 
                            master..sysusages
                        WHERE 
                            dbid = 4
                          AND 
                            segmap = 3
                        ';
            my $sth = $dbh->prepare($query);

            $sth->execute;

            while (@row = $sth->fetchrow) {
                    $size = $row[0];
            }

            $sth->finish;

            $query  = 'select @@version';
            $sth    = $dbh->prepare($query);

            $sth->execute;

            while (@row = $sth->fetchrow) {
                    $version = $row[0];
            }

            $sth->finish;

            $dbh->disconnect;

            $size = $size * 16 / 1024;
            say "SID: $sid, SIZE: $size, VERSION: $version";
        }
}