【问题标题】:Iterating the results returned from fetchall_arrayref迭代从 fetchall_arrayref 返回的结果
【发布时间】:2019-12-29 19:37:27
【问题描述】:

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

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

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

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

我能够做到,但我对我的实施不满意,因为我必须致电 doSomethingWithNames()twice。

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 没有进入循环 for 最后一次迭代为fetch* 返回undef

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

【问题讨论】:

  • 提示:语言的名称是“Perl”,而不是“PERL”。这不是首字母缩写词。
  • 提示:eq 用于比较字符串。使用== 比较数字。
  • 提示:将a 放在数组名称前面是没有意义的。
  • 提示:最后的doSomethingWithNames(\@aParentRecords); 应该是doSomethingWithNames(\@aParentRecords) if @aParentRecords;(当没有要获取的记录时)。
  • 提示:仅在 returndienextlast 或其他一些流控制运算符后使用 andor。在别处使用&&||

标签: perl dbi fetchall


【解决方案1】:

诀窍是通过将现有循环转换为无限循环来推迟现有循环。不过,这需要检查循环终止条件 (!$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);
}

【讨论】:

  • 完美运行@ikegami。感谢您的解决方案和提示!
猜你喜欢
  • 1970-01-01
  • 2014-12-18
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多