Perl의 DBI가 명세서를 준비하는 오류가 발생했을 때 프로그램을 중단하지 않으려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/836827

  •  08-07-2019
  •  | 
  •  

문제

데이터베이스에 다른 모든 테이블 이름이 포함 된 테이블을 통과하는 스크립트를 만들고 있습니다. 각 행을 구문 분석하므로 테이블이 비어 있는지 확인합니다.

select count(*) cnt from $table_name 

일부 테이블은 더 이상 스키마에 존재하지 않으며 그렇게한다면

select count(*) 

명령 프롬프트에 직접, 오류를 반환합니다.

206 : 지정된 표 (ADM_RPT_REC)는 데이터베이스에 없습니다.

내부 Perl에서 실행하면 처음 까지이 부분을 추가합니다.

dbd :: informix :: db 준비 실패 : SQL : -

이 SQL 문을 준비하려고 할 때 프로그램이 종료되지 않도록하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

작업 코드 - '상점'데이터베이스가 있다고 가정합니다.

#!/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 중요한 - 배열 컨텍스트 대 스칼라 컨텍스트입니다.

다른 팁

하나의 옵션은 $ dbh를 구성 할 때 RaidError => 1을 사용하지 않는 것입니다. 다른 하나는 준비 블록에 준비를 감싸는 것입니다.

다음과 같은 평가 블록에 실패 할 수있는 통화 만 넣으십시오.

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는 시스템 카탈로그 테이블 세트에서 이와 같은 메타 데이터를 유지합니다. 이 경우 시스템을 원합니다.

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(*) 테이블에. 시스템 카탈로그 테이블의 전체 문서화는 SQL에 대한 IBM Informix 안내서 (경고 PDF입니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top