كيف يمكنني تجنب برنامج الإقلاع عن التدخين عندما يصادف DBI بيرل خطأ إعداد بيان؟

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

  •  08-07-2019
  •  | 
  •  

سؤال

وأنا صنع السيناريو الذي يذهب من خلال الجدول الذي يحتوي على كافة أسماء الجداول الأخرى في قاعدة البيانات. كما يوزع كل صف، فإنه بالتحقق مما إذا كان الجدول فارغ من قبل

select count(*) cnt from $table_name 

وبعض الجداول لا وجود لها في المخطط بعد الآن، وإذا فعلت ذلك

select count(*) 

ومباشرة في موجه الأوامر، تقوم بإرجاع خطأ:

<اقتباس فقرة>   

206: الجدول المحدد (adm_rpt_rec) غير موجود في قاعدة البيانات

عند I تشغيلها من داخل بيرل، فإنه يلحق ذلك إلى البداية:

<اقتباس فقرة>   

وDBD :: :: ينفورميكس ديسيبل باعداد فشل: 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 حاسمة - السياق مجموعة مقابل السياق العددية

.

نصائح أخرى

وخيار واحد هو عدم استخدام RaiseError => 1 عند بناء $ DBH. والآخر هو التفاف إعداد في كتلة وحدة التقييم.

وضعت للتو المكالمات التي قد تفشل في كتلة وحدة التقييم مثل هذا:

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

وعلى الرغم من أن في هذه الحالة، لأنك تستخدم ينفورميكس، لديك خيار أفضل بكثير: الجداول كتالوج النظام. ينفورميكس تبقي الفوقية مثل هذا في مجموعة من الجداول كتالوج النظام. في هذه الحالة تريد 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(*) على الطاولة. ويمكن الاطلاع على وثائق كاملة من الجداول كتالوج النظام في <لأ href = "http://www.ibm.com/software/data/informix/pubs/library/interim/ct1spna-pdf.html" يختلط = "نوفولو noreferrer" > IBM دليل ينفورميكس إلى SQL (وتحذير هذا هو PDF).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top