繁体   English   中英

错误消息:无法对未定义的值调用方法“做”

[英]Error Message: Can't call method “do” on an undefined value

# #################################################
#       Subroutine to add data to the table BlastSearch
#       Could be redone to be more general, but it seems more 
#       efficient to add data as it is pulled from the xml.
# ################################################# 
sub addData {
    my (@data, $dbhandle) = @_;
    print join(", ", @data) . "\n";
    my $sqlcmd = "insert into BlastSearch values('" . join("','",@data) . "')";
    $dbhandle->do($sqlcmd) or die $DBI::errstr;
}

这给出了错误消息“无法在未定义的值上调用方法“ do”。 此特定方法中是否有任何导致问题的原因? 如果需要,我可以添加更多脚本。 我唯一的猜测是它与“ @data”有关,该代码填充在以下代码中:

# #################################################
#       Subroutine to find the:
#           Accession id
#           e-value (Hsp_evalue)
#           number of identites (Hsp_identity)
#       of the top five matches.
# #################################################
sub parseBlastXML {
    my ($file, $dbhandle) = @_;
    my $xml = new XML::Simple();
    my $data = $xml->XMLin($file, forcearray=>[qw(Hit)], keyattr=>[]);
    my $entry_node = $data->{BlastOutput_iterations};
    my $iterhit = $entry_node->{Iteration}->{Iteration_hits}->{Hit};

    #quick find of uniprotID
    my $uniProtID = substr($file, 0, 6);

    my $count = 0;
    foreach my $val (@$iterhit) {
        my @dataarray;
        if ($val->{Hit_hsps} && $count < 5) {
            print "\n";
            print "Hit accession: " . $val->{Hit_accession} . "\n"; 
            print "e-value: " . $val->{Hit_hsps}->{Hsp}->{Hsp_evalue} . "\n"; 
            print "number of ID's: " . $val->{Hit_hsps}->{Hsp}->{Hsp_identity} . "\n";
            push(@dataarray, $val->{Hit_accession}); 
            push(@dataarray, $val->{Hit_hsps}->{Hsp}->{Hsp_evalue}); 
            push(@dataarray, $val->{Hit_hsps}->{Hsp}->{Hsp_identity});
            push(@dataarray, $uniProtID);

            addData(@dataarray, $dbhandle);

            $count ++;
        }
    }
    return $data;
}

以下是一个错误,因为@data将始终使用@_所有值,而未定义$dbhandle

sub addData {
    my (@data, $dbhandle) = @_;    # $dbhandle will always be undefined

要解决此问题,您需要对参数进行重新排序,并始终使数组位于赋值的最后。

sub addData {
    my ( $dbhandle, @data ) = @_;

    ...;
}

sub parseBlastXML {
    ...;
    addData( $dbhandle, @dataarray );

注意:也可以将dbh pop参数列表的末尾。 但是,这样的编码风格不是一个好主意。

“此外,如果有人能比数组和联接更好的方法将值添加到sqlite表的一行中,那将不胜感激。”

@data数组的大小总是一样吗? 我想是这样,因为您在INSERT语句中没有指定列列表,所以最好的方法是编写

sub add_data {
    my ($dbhandle, @data) = @_;
    my $insert = $dbhandle->prepare('INSERT INTO BlastSearch VALUES (?, ?, ?, ?)');
    $insert->execute(@data) or die $DBI::errstr;
}

与正确的数量? 占位符,显然。 prepare调用就像编译该语句一样,理想情况下,您应该在程序首次启动时执行一次,然后可以使用不同的参数多次调用execute

如果@data大小确实有所不同,则不会丢失所有内容。 你可以做这样的事情

    my $insert = sprintf 'INSERT INTO BlastSearch VALUES (%)',
        join ', ', map '?', @data;
    $insert = $dbhandle->prepare($insert);
    $insert->execute(@data) or die $DBI::errstr;

但请注意,每次参数计数更改时,您都必须调用prepare

还需要注意的是你的标识符addData最好应add_data ,如大写字母通常被保留,全局标识符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM