首页 > 解决方案 > 迭代从 fetchall_arrayref 返回的结果

问题描述

我有一个 sql,其中我正在获取少量记录,按全名排序。

我的要求是提取相似名称的块,然后对其进行一些操作。

说,sql返回一些包含名称的记录[name1,name1,name2,name3,name3]

我需要将它们拆分为[name1,name1] , [name2] , [name3,name3]

我能够做到,但我对我的实施不满意,因为我必须打电话doSomethingWithNames()两次。

while (my $paRecs = $pStatementHandle->fetchall_arrayref({}, 3)){
   foreach my $phRec(@{$paRecs}){
       my $pCurrentName = $phRec->{'FULL_NAME'};
       if ((scalar(@aParentRecords) eq 0) or ($aParentRecords[-1] eq $pCurrentName)){
           push(@aParentRecords, $pCurrentName);
       } else {
           doSomethingWithNames(\@aParentRecords);
           @aParentRecords= ();
           push(@aParentRecords, $pCurrentName);
       }
   }
};
doSomethingWithNames(\@aParentRecords); # This should be inside while loop  

我相信遇到了这个问题,因为 while 没有作为fetch*返回的最后一次迭代进入循环undef

听起来是基本的 PERL 东西,但尝试了许多循环构造,但都没有成功。任何指针都会有很大帮助

标签: perldbifetchall

解决方案


诀窍是通过将现有循环转换为无限循环来推迟现有循环。不过,这需要检查循环终止条件 ( !$rows) 两次。

my $rows = [];
my $prev_name = '';
my @group;
while (1) {
   $rows = $sth->fetchall_arrayref({}, 3) if !@$rows;

   if (!$rows || $rows->[0]->{FULL_NAME} ne $prev_name)
      if (@group) {
         do_something(\@group);
         @group = ();
      }

      last if !$rows;
   }

   $prev_name = $rows->[0]->{FULL_NAME};
   push @group, shift(@$rows);
}

推荐阅读