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

问题描述 投票:0回答:1

我需要查询一组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次迭代后崩溃。因此,第五个数据库的连接不再起作用。

Can't call method "prepare" on an undefined value at ./check_sybasedbs.pl line 36.

第36行是语句1的准备。

我尝试将睡眠命令放在各个位置。我还试图明确清除通过undef重用的变量。现在我没主意了,非常感谢您的投入。

database perl dbi
1个回答
0
投票

您的代码可以作为下面的示例编写(请参见if ... else ...$dbh块]

use strict;
use warnings;
use feature 'say';

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";
        }
}

注意: use strict; use warnings;有助于避免许多陷阱,use diagnostics;有助于在困难的情况下识别问题

NOTE: $sth->fetchrow_hashref允许按名称显示地址散列元素,无需像$sth->fetch_rowarray那样对数组的索引进行计数

© www.soinside.com 2019 - 2024. All rights reserved.