如何检查 Perl 中 fetchall_arrayref 方法返回的行?

How to check rows returned by fetchall_arrayref method in Perl?

我试图理解以下代码,特别是第 4、5 和 6 行中发生的事情。

我已经理解了其中的大部分内容,但似乎无法理解第 4 行中 @$r != 1; 所做的事情(@$r 是否代表返回的行数?)以及类似的是什么发生在第 5 行的 @$r[0] 和第 6 行的 @$rr[0]

1 my $sth = $dbh->prepare(" a select statement ");
2    $sth->execute();
3   my $r = $sth->fetchall_arrayref();
4  die "Failed to select " if !defined($r) || @$r != 1;
5   my $rr = @$r[0];
6    my $rec = @$rr[0];
7   print "Rec is $rec\n";

在标量上下文中评估数组(引用)returns 数组中的元素数。您其他问题的答案是,它只是使用难看的语法和无用的中间变量的标准取消引用。

不过,我相信授人以渔,所以考虑一下这段代码,它本质上就是您正在使用的代码:

use strict;
use warnings;

use Data::Dumper;

my $r   = [[1, 2, 3]];
my $rr  = @$r[0];
my $rec = @$rr[0];

print Dumper($r, $rr, $rec);

输出:

$VAR1 = [
          [
            1,
            2,
            3
          ]
        ];
$VAR2 = $VAR1->[0];
$VAR3 = 1;

现在应该很容易看出发生了什么,您可以看到每个变量的内容,对吧?

fetchall_arrayref() return 是对所有行的数组的引用,其中每个元素也是对包含该行元素的数组的引用。

然后 die 行检查

  1. 顶级引用 $r 已定义(调用有效),并且

  2. 该数组的大小 @$r 正好是 1 – 因此,该数组只包含一个元素。这背叛了查询将 return 一行的期望,并且由于代码为此准备 die 它可能会要求一行,由 fetchrow_arrayref or fetchrow_array.

@$r 取消引用 $r arrayref,在 != 强加的标量上下文中,我们确实得到了列表中的元素数。

第 5 行非常具有误导性,至少可以说,即使语法恰好是合法的:它提取第一个元素并将其提供给标量,但使用通常暗示的 @$r[0] 语法我们得到一个列表,通过它的印记 @。它等同于 @{$r}[0] 并且是对符号的滥用。

它应该清楚地获取第一个元素,如果这是意图的话

my $rr = $r->[0];

或者取消引用它以获得整个数组

my @row = @{ $r->[0] };

如果需要的话。

您查询的最后一行使用检索到的 $rr 引用执行完全相同的操作。但是第一个arrayref(row)的第一个元素很容易直接得到

my $rec = $r->[0]->[0];  # or $r->[0][0]

用什么替换第 5 行和第 6 行。

参见 perlreftut and perldsc