Perl 错误消息:Can';t调用方法";“做”;关于未定义的值

Perl 错误消息:Can';t调用方法";“做”;关于未定义的值,perl,sqlite,xml-parsing,perl-module,Perl,Sqlite,Xml Parsing,Perl Module,这会在未定义的值上显示错误消息“无法调用方法”do“。此特定方法中是否有导致问题的原因?如果需要,我可以添加更多的脚本。我唯一的猜测是它与“@data”有关,下面的代码中填充了它: # ################################################# # Subroutine to add data to the table BlastSearch # Could be redone to be more general, but it

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

# #################################################
#       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;
}
##################################################
#用于查找的子例程:
#登录id
#e值(Hsp_评估值)
#标识数(Hsp_标识)
#前五名的比赛。
# #################################################
子解析XML{
我的($file,$dbhandle)=@;
my$xml=new xml::Simple();
my$data=$xml->XMLin($file,forcearray=>[qw(Hit)],keyatt=>[]);
我的$entry_节点=$data->{BLOBOUTPUT_迭代次数};
my$iterhit=$entry_node->{Iteration}->{Iteration_hits}->{Hit};
#单蛋白的快速发现
my$uniProtID=substr($file,0,6);
我的$count=0;
foreach my$val(@$iterhit){
我的@dataarray;
如果($val->{Hit_hsps}&&$count<5){
打印“\n”;
打印“点击加入:.$val->{Hit_加入}.\n”;
打印“e-value:.$val->{Hit_hsps}->{Hsp}->{Hsp_evalue}.\n”;
打印“ID编号:“.$val->{Hit_hsps}->{Hsp}->{Hsp_identity}.”\n”;
push(@dataarray,$val->{Hit_});
push(@dataarray,$val->{Hit_hsps}->{Hsp}->{Hsp_evalue});
push(@dataarray,$val->{Hit_hsps}->{Hsp}->{Hsp_identity});
push(@dataarray,$uniProtID);
addData(@dataarray,$dbhandle);
$count++;
}
}
返回$data;
}

以下是一个bug,因为
@data
总是会将
@
中的所有值发出咕噜声,使
$dbhandle
未定义

# #################################################
#       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;
}
要修复此问题,您需要对参数重新排序,并始终使数组位于赋值的最后一位

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

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

以下是一个错误,因为
@data
总是会将
@
中的所有值弄混,从而使
$dbhandle
未定义

# #################################################
#       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;
}
要修复此问题,您需要对参数重新排序,并始终使数组位于赋值的最后一位

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

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

此外,如果有人有比数组和联接更好的向sqlite表的行添加值的方法,我们将不胜感激

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

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

    ...;
}

sub parseBlastXML {
    ...;
    addData( $dbhandle, @dataarray );
显然,具有正确数量的
占位符。
prepare
调用类似于编译语句,理想情况下,您应该在程序首次启动时只执行一次,然后可以使用不同的参数调用
execute

如果
@data
的大小确实不同,那么所有数据都不会丢失。你可以这样做

sub add_data {
    my ($dbhandle, @data) = @_;
    my $insert = $dbhandle->prepare('INSERT INTO BlastSearch VALUES (?, ?, ?, ?)');
    $insert->execute(@data) or die $DBI::errstr;
}
但请注意,每次参数计数更改时,您都必须调用
prepare


还要注意,标识符
addData
最好是
add\u data
,因为大写字母通常保留给全局标识符。

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

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

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

    ...;
}

sub parseBlastXML {
    ...;
    addData( $dbhandle, @dataarray );
显然,具有正确数量的
占位符。
prepare
调用类似于编译语句,理想情况下,您应该在程序首次启动时只执行一次,然后可以使用不同的参数调用
execute

如果
@data
的大小确实不同,那么所有数据都不会丢失。你可以这样做

sub add_data {
    my ($dbhandle, @data) = @_;
    my $insert = $dbhandle->prepare('INSERT INTO BlastSearch VALUES (?, ?, ?, ?)');
    $insert->execute(@data) or die $DBI::errstr;
}
但请注意,每次参数计数更改时,您都必须调用
prepare


另外请注意,您的标识符
addData
最好是
add\u data
,因为大写字母通常保留给全局标识符。

此外,如果有人有比数组和联接更好的方法向sqlite表的行添加值,我们将不胜感激。此外,如果有人能比array和join更好地向sqlite表的行中添加值,那将不胜感激;我的@data=@如果要保持参数的当前顺序。添加了关于从列表末尾开始的注释。不推荐。我只是在两个地方都翻了一下。真棒的答案,我自己不会得到的。对Perl来说还是太新了。谢谢@Stats4224:do使用嵌入值的SQL字符串也是不好的形式。您应该
准备一个带有占位符的字符串,并在调用
execute
my$dbhandle=pop时传递实际值;我的@data=@如果要保持参数的当前顺序。添加了关于从列表末尾开始的注释。不推荐。我只是在两个地方都翻了一下。真棒的答案,我自己不会得到的。对Perl来说还是太新了。谢谢@Stats4224:do
使用嵌入值的SQL字符串也是不好的形式。您应该
准备一个带有占位符的字符串,并在调用
execute
时传递实际值。谢谢!这实际上解释了很多。我的@data数组的大小始终相同。你看起来更干净了。谢谢!谢谢这实际上解释了很多。我的@data数组的大小始终相同。你看起来真是太棒了