我正在创建一个脚本,该脚本通过一个包含数据库中所有其他表名的表。在解析每一行时,它会通过
检查表是否为空select count(*) cnt from $table_name
架构中不存在某些表格,如果我这样做了
select count(*)
直接进入命令提示符,它返回错误:
206:指定的表(adm_rpt_rec)不在数据库中。
当我从Perl中运行它时,它会将其添加到开头:
DBD :: Informix :: db prepare failed:SQL: -
如何在尝试准备此SQL语句时避免程序退出?
答案 0 :(得分:3)
一个选项是不使用RaiseError => 1构造$ dbh时。另一种是将准备包装在一个eval块中。
答案 1 :(得分:3)
只需将可能失败的调用放在eval块中,如下所示:
for my $table (@tables) {
my $count;
eval {
($count) = $dbi->selectrow_array("select count(*) from $table");
1; #this is here so the block returns true if it succeeds
} or do {
warn $@;
next;
}
print "$table has $count rows\n";
}
虽然在这种情况下,由于您使用的是Informix,因此您有一个更好的选择:系统目录表。 Informix将这样的元数据保存在一组系统目录表中。在这种情况下,您需要systables:
my $sth = $dbh->prepare("select nrows from systables where tabname = ?");
for my $table (@tables) {
$sth->execute($table);
my ($count) = $sth->fetchrow_array;
$sth->finish;
unless (defined $count) {
print "$table does not exist\n";
next;
}
print "$table has $count rows\n";
}
这比表格count(*)
更快,更安全。可以在IBM Informix Guide to SQL中找到系统目录表的完整文档(警告这是PDF)。
答案 2 :(得分:2)
工作代码 - 假设您有一个'商店'数据库。
#!/bin/perl -w
use strict;
use DBI;
my $dbh = DBI->connect('dbi:Informix:stores','','',
{RaiseError=>0,PrintError=>1}) or die;
$dbh->do("create temp table tlist(tname varchar(128) not null) with no log");
$dbh->do("insert into tlist values('systables')");
$dbh->do("insert into tlist values('syzygy')");
my $sth = $dbh->prepare("select tname from tlist");
$sth->execute;
while (my($tabname) = $sth->fetchrow_array)
{
my $sql = "select count(*) cnt from $tabname";
my $st2 = $dbh->prepare($sql);
if ($st2)
{
$st2->execute;
if (my($num) = $st2->fetchrow_array)
{
print "$tabname: $num\n";
}
else
{
print "$tabname: error - missing?\n";
}
}
}
$sth->finish;
$dbh->disconnect;
print "Done - finished under control.\n";
运行上面代码的输出。
systables: 72
DBD::Informix::db prepare failed: SQL: -206: The specified table (syzygy) is not in the database.
ISAM: -111: ISAM error: no record found. at xx.pl line 14.
Done - finished under control.
这打印了错误(PrintError=>1
),但仍在继续。将1更改为0,不会出现错误。 $tabname
和$num
声明中的括号是至关重要的 - 数组上下文与标量上下文。