问题:
我在Perl中使用DBI
,需要通过记录集中的记录进行双嵌套循环。
在过去,我使用过while语句,如:
my $someQuery = "SELECT * FROM foo;";
my $sth = $dbh->prepare($someQuery);
$sth->execute();
while (my $ref = $sth->fetchrow_hashref()) {
my $someVariable = "$ref->{'dbFieldName'}";
# do stuff
}
使用for loop
代替while loop
,我想要实现的目标很容易,但我需要知道如何通过行索引以及总行数。关于如何做到这一点的任何想法?
奖励积分:
以上将帮助我解决一个问题,但我希望能有更好的技巧让我自己解决这个问题。我在Eclipse中使用Perl EPIC,它没有提供任何类型的上下文预测/自动完成(或者如果它我不知道如何启用它)。有没有办法为Eclipse启用这个或不同的附加组件来显示上下文,所以我可以看到有哪些选项可用?
答案 0 :(得分:1)
有两种方法可以获得行号:
my $row_num = 0;
while (my $row = $sth->fetchrow_hashref) {
$row_num++;
# Do stuff
}
这取决于您使用的DBMS,但您可以在MySQL中执行类似的操作:
$dbh->do('SET @row_num := 0');
my $statement = <<'SQL';
SELECT @row_num := @row_num + 1 AS row_num,
foo,
bar
FROM table
SQL
my $sth = $dbh->prepare($statement);
$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
say $row->{row_num};
# Do stuff
}
您可以使用$sth->rows
,但需要注意以下几点:
通常,您只能依赖非
SELECT
execute
之后的行计数(对于某些特定操作,例如UPDATE
和DELETE
),或者SELECT
语句的行。对于
SELECT
语句,通常不可能知道将返回多少行,除非通过全部获取它们。某些驱动程序将返回应用程序到目前为止所获取的行数,但其他驱动程序可能会返回-1,直到获取所有行为止。因此,不建议使用rows方法或$DBI::rows
和SELECT
语句。获取
SELECT
的行计数的另一种方法是使用与查询相同的“...”执行"SELECT COUNT(*) FROM ..."
SQL语句,然后从中获取行计数。 / p>
但是,如果你在获取它时已经计算了每一行,你可以简单地使用它。
答案 1 :(得分:0)
下面是 hack 我将结果导入数组结构,这将允许我轻松地进行嵌套循环。如果他们有更好的方法,希望其他人会发布答案。
my @results;
my $fieldFirstName = 0;
my $fieldLastName = 1;
my $fieldAddress = 2;
my $i = 0;
my $someQuery = "SELECT FirstName, LastName, Address FROM foo;";
my $sth = $dbh->prepare($someQuery);
$sth->execute();
while (my $ref = $sth->fetchrow_hashref()) {
$results[$i][$fieldFirstName] = "$ref->{'FirstName'}";
$results[$i][$fieldLastName] = "$ref->{'LastName'}";
$results[$i][$fieldAddress] = "$ref->{'Address'}";
$i++;
}
$sth->finish();
my $resultsRecordCount = @results;