Database 数据库连接脚本在4次成功连接后崩溃
我需要查询一组SAP sybase数据库以获取一些信息,并将其打印为逗号分隔的列表。所以我想我写了一个perl脚本,通过DBI模块连接到这些数据库中的任何一个。这是我想到的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;
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";
}
}