1

I'm making a script that goes through a table that contains all the other table names on the database. As it parses each row, it checks to see if the table is empty by

select count(*) cnt from $table_name 

Some tables don't exist in the schema anymore and if I do that

select count(*) 

directly into the command prompt, it returns the error:

206: The specified table (adm_rpt_rec) is not in the database.

When I run it from inside Perl, it appends this to the beginning:

DBD::Informix::db prepare failed: SQL: -

How can I avoid the program quitting when it tries to prepare this SQL statement?

4

3 に答える 3

3

1 つのオプションは、$dbh を構築するときに RaiseError => 1 を使用しないことです。もう 1 つは、eval ブロッ​​クで準備をラップすることです。

于 2009-05-07T20:24:59.167 に答える
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 であることに注意してください)。

于 2009-05-07T22:00:34.943 に答える
2

作業コード-「stores」データベースがあると仮定します。

#!/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は重要です-配列コンテキストとスカラーコンテキスト。

于 2009-05-07T22:55:29.040 に答える