[英]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.