# #################################################
# 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;
}
这会在“未定义的值”上显示错误消息“无法调用方法”。这种特殊方法中是否有任何导致问题的原因?如果需要,我可以添加更多脚本。我唯一的猜测是它与'@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;
}
答案 0 :(得分:3)
以下是一个错误,因为@data
将始终淹没@_
中的所有值,而$dbhandle
未定义。
sub addData {
my (@data, $dbhandle) = @_; # $dbhandle will always be undefined
要修复,您需要重新排序参数,并始终将数组放在赋值中。
sub addData {
my ( $dbhandle, @data ) = @_;
...;
}
sub parseBlastXML {
...;
addData( $dbhandle, @dataarray );
注意:也可以在参数列表的末尾pop
dbh。但是,这种编码风格并不是一个好主意。
答案 1 :(得分:1)
&#34;此外,如果有人有更好的方法将值添加到sqlite表的行而不是数组并加入,那么我们将非常感激。&#34;
您的@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
,因为大写字母通常是为全局标识符保留的。