簡體   English   中英

當Perl的DBI在准備語句時遇到錯誤時,如何避免程序退出?

[英]How can I avoid the program quitting when Perl's DBI encounters an error preparing a statement?

我正在編寫一個遍歷包含數據庫中所有其他表名的表的腳本。 解析每一行時,它會檢查表是否為空

select count(*) cnt from $table_name 

模式中不再存在某些表,如果我這樣做了

select count(*) 

直接進入命令提示符,它返回錯誤:

206:指定的表(adm_rpt_rec)不在數據庫中。

當我從Perl內部運行它時,它會附加到開頭:

DBD :: Informix :: db准備失敗:SQL:-

在嘗試准備此SQL語句時如何避免程序退出?

一種選擇是在構造$ dbh時不使用RaiseError => 1。 另一種是將准備包裝在評估塊中。

只需將可能失敗的呼叫放在這樣的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 SQL指南》 (請注意這是PDF)中找到系統目錄表的完整文檔。

工作代碼-假設您有一個“商店”數據庫。

#!/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聲明中的括號至關重要-數組上下文與標量上下文。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM