Wie kann ich das Programm vermeiden beenden, wenn Perl DBI einen Fehler entdeckt, eine Erklärung vorbereitet?

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

  •  08-07-2019
  •  | 
  •  

Frage

Ich mache ein Skript, das durch einen Tisch geht, das alle anderen Tabellennamen in der Datenbank enthält. Da es jede Zeile analysiert, überprüft er, ob die Tabelle

leer ist
select count(*) cnt from $table_name 

Einige Tabellen existieren nicht im Schema mehr und wenn ich das

select count(*) 

direkt in die Eingabeaufforderung, es gibt den Fehler:

  

206:. Die angegebene Tabelle (adm_rpt_rec) ist nicht in der Datenbank

Wenn ich es von innen Perl laufen, es hängt dies zum Anfang:

  

DBD :: Informix :: db prepare fehlgeschlagen: SQL: -

Wie kann ich das Programm verlassen vermeiden, wenn es diese SQL-Anweisung vorzubereiten versucht?

War es hilfreich?

Lösung

Arbeits Code - vorausgesetzt, Sie eine 'speichert' Datenbank

.
#!/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";

Ausgabe vom Laufen Sie den Code oben.

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.

Dies gedruckt, um den Fehler (PrintError=>1), aber fortgesetzt. Ändern Sie die 1 auf 0 und kein Fehler angezeigt wird. Die Klammern in den Erklärungen von $tabname und $num sind entscheidend - Array Kontext vs Skalarkontext

.

Andere Tipps

Eine Option ist nicht Raiseerror => 1 zu verwenden, wenn $ dbh zu konstruieren. Die andere ist die Vorbereitung in einem eval-Block zu wickeln.

Sie einfach die Anrufe setzen, die in einem eval-Block wie diese fehlschlagen:

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";
}

Obwohl in diesem Fall, da Sie Informix verwenden, haben Sie eine viel bessere Option: die Systemkatalogtabellen. Informix hält Metadaten wie dies in einer Reihe von Systemkatalogtabellen. In diesem Fall möchten Sie 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";
} 

Dies ist schneller und sicherer als count(*) gegen den Tisch. Die vollständige Dokumentation der Systemkatalogtabellen können in IBM Informix Guide to SQL (Warnung dies ist ein PDF).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top