Сценарий подключения к базе данных падает после 4 успешных подключений - PullRequest
0 голосов
/ 06 марта 2020

Мне нужно запросить у группы баз данных 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. Теперь у меня нет идей, и я был бы очень признателен за ваш вклад.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Ваш код может быть написан как пример ниже (см. if ... else ... блок для $dbh)

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

ПРИМЕЧАНИЕ: use strict; use warnings; помогает избежать многих ловушек, use diagnostics; помогает выявить проблему в сложных случаях

ПРИМЕЧАНИЕ: $sth->fetchrow_hashref разрешает адрес ha sh элементу по имени, нет необходимости считать индекс массива, как в случае $sth->fetch_rowarray

0 голосов
/ 06 марта 2020

в своем наивном мышлении я спрятал несколько строк кода, которые, по моему убеждению, не могли быть причиной этого неправильного поведения. Как оказалось, так и было. Таким образом, причиной моей проблемы была простая логическая ошибка, из-за которой пароль, который использовался после подключения к определенной БД, был неверным.

...