2
#!/usr/bin/perl -C0
use strict;
use warnings;   
use DBI;

sub agg_verification
{
my ($list,$tblname,$values);
my $res1=undef;
my $res2=undef;

    #First DB Connection******
    my $connstr = "ENG=xxx;CommLinks=tcpip{port=xxx};UID=xxx;PWD=xxx";
    my $dbh = DBI->connect( "DBI:SQLAnywhere:$connstr", '', '', {AutoCommit => 0} ) or warn $DBI::errstr;
    my $stmt="select col1||':'||col3 as a, col2||'('||col3||')' as b from table where col1 like '%xxxx:((15))%'"; #making 'a' as primary key for fetchall_hashref() later.
    my $sth=$dbh->prepare($stmt) or warn $DBI::errstr;
    $sth->execute() or warn $DBI::errstr;

    #Second DB Connection******
    my $connstr1 = "ENG=xxx;CommLinks=tcpip{port=xxx};UID=xxx;PWD=xxx";
    my $dbh1 = DBI->connect( "DBI:SQLAnywhere:$connstr1", '', '', {AutoCommit => 0} ) or warn $DBI::errstr;
    my ($sth1,$stmt1,$stmt2);
    #creating, opening and writing the result in a file 
       open my $fh, '+>>', "/eniq/home/dcuser/output.txt" or warn "Cannot open output.txt: $!";

       my $res = $sth->fetchall_hashref('a');

       foreach my $key(sort keys %$res) {
            my @col1 = $res->{$key}->{'a'};
            $list=\@col1;
                foreach my $item(@$list)
                    {
                        my @values=${$res}{$item}->{'b'};
                        $values=\@values;
                        my @tblname=$item=~ m/[(\w*)(\:)](DC\w*)/; #trimming table name
                        $tblname =\@tblname;
                        #print $fh "TABLENAME :@$tblname\n";

                            foreach my $raw(@$tblname) #Extracting _RAW data*********************
                            {
                                $raw.="_RAW";
                                chomp($raw);
                                $stmt1 = "select @$values from $raw";
                                $stmt2 = "";
                                $sth1=$dbh1->prepare($stmt1) or warn $DBI::errstr;
                                $sth1->execute() or warn $DBI::errstr;
                                my $max_rows1 = 5_000;
                                $res1 = $sth1->fetchall_arrayref(undef,$max_rows1);

                                                }
                            foreach my $day(@$tblname) #Extracting _DAY DATA******************** 
                            {
                                $day  =~ s/(\_RAW)//;
                                chomp($day);
                                $day .="_DAY";
                                $stmt2 = "select @$values from $day";
                                $sth1=$dbh1->prepare($stmt2) or warn $DBI::errstr;
                                $sth1->execute() or warn $DBI::errstr;
                                my $max_rows = 5_000;
                                $res2 = $sth1->fetchall_arrayref(undef,$max_rows);                              
                                                }

                                if(@$res1 == @$res2)
                                {
                                    print $fh "PASS at @$values\n";
                                                }
                                else
                                {
                                    print $fh "FAIL at @$values\n";
                                                }
                                                    }
                                                        }


    close $fh or warn "Couldn't close file properly";
        $sth1->finish();
        $sth->finish();
        $dbh1->disconnect;
        $dbh->disconnect;
}
agg_verification();

皆さん、$res1 と $res2 の数値を比較したいのですが、合格または不合格の結果が得られません。私の出力は、変更に関係なくすべて「合格」です。ライブラリを更新または追加する権限がないため、外部 CPAN ライブラリを使用せずに上記のコードで配列参照の値を比較する方法を提案してください。

4

1 に答える 1

2

変更に関係なく、私の出力はすべて「合格」です

これは、参照解除された両方の配列の要素数を比較するだけの以下の条件によるものです。

if(@$res1 == @$res2)

両方の配列参照の内容を比較したい場合(質問によると数値です)、次のことができます

#!/usr/bin/perl
use strict;
use warnings;
use Test::More 'no_plan';
my $res1 = [5,8,10,12];
my $res2 = [5,8,10,12];
is_deeply( $res1, $res2, 'Compare arrayref' );

上記の場合の出力:

chankey@pathak:~/Desktop$ perl test.pl 
ok 1 - Compare arrayref
1..1

それらが等しくない場合:

my $res1 = [5,8,10,12];
my $res2 = [3,8,10,12];

次に、以下の詳細な出力が得られ、どの値が等しくないかを簡単に確認できます

chankey@pathak:~/Desktop$ perl test.pl 
not ok 1 - Compare arrayref
#   Failed test 'Compare arrayref'
#   at test.pl line 7.
#     Structures begin differing at:
#          $got->[0] = '5'
#     $expected->[0] = '3'
1..1
# Looks like you failed 1 test of 1.

2 つの arrayref を比較する方法について 1 つの方法を示しましたが、以下の質問で回答されている他の方法を参照することをお勧めします (最初に配列を逆参照してから比較を行うようにしてください)。


モジュールを使用しないソリューション

#!/usr/bin/perl
use strict;
use warnings;
my $res1 = [5,8,10,12];
my $res2 = [3,8,10,12];
foreach my $index (0..$#{$res1}){
    if ($res1->[$index] == $res2->[$index]){
        print "Index: $index, Equal: YES";
    }
    else{
        print "Index: $index, Equal: NO";
        print " [Expected: $res1->[$index], GOT: $res2->[$index]]";
    }
    print "\n";
}

出力:

chankey@pathak:~/Desktop$ perl test.pl 
Index: 0, Equal: NO [Expected: 5, GOT: 3]
Index: 1, Equal: YES
Index: 2, Equal: YES
Index: 3, Equal: YES

チャットに関する議論に従って:

$res1 と $res2 の各インデックスに arrayrefs があるためです。したがって、以下のようなものを使用する必要があります。

#!/usr/bin/perl
use strict;
use warnings;

my $res1 = [[5],[4],[3],[2]];
my $res2 = [[5],[4],[3],[1]];
foreach my $index (0..$#{$res1}){
    foreach my $inner_index (0..$#{$res1->[$index]}){
        if ($res1->[$index]->[$inner_index] == $res2->[$index]->[$inner_index]){
            print "Equal!! expected: $res1->[$index]->[$inner_index] got: $res2->[$index]->[$inner_index]\n" ;
        }
        else{
            print "Not Equal!! expected: $res1->[$index]->[$inner_index] got: $res2->[$index]->[$inner_index]\n" 
        }

    }

}
于 2016-08-29T10:41:26.107 に答える