2014-05-16 43 views
0

我希望有人能够帮助我。我是Perl新手,通常从我编写的一些小脚本中获得一些好的结果,但是,我被困在一个正在处理的新脚本的嵌套while循环中。perl嵌套同时循环 - 半工作

我放在一起的脚本执行两个mysql select语句,然后将结果放入单独的数组中。然后我想检查第一个数组中的第一个元素与第二个数组中的所有结果。然后移至第一个数组中的第二个元素,并检查秒数组中的所有结果等等。

脚本的目标是找到第一阵列中的一个IP地址,看哪个子网它适合在第二...

我发现的情况是,脚本运行,通过仅在第一个数组上的第一个元素和第二个数组上的所有元素,然后停止。

下面是perl脚本的摘录 - 如果任何人都可以指出我正确的方向,我会非常感激。

my @ip_core_wan_field; 

while (@ip_core_wan_field = $wan_core_collection->fetchrow_array()) { 
    my $coreipAddr = @ip_core_wan_field[1]; 
    my @ip_wan_field; 
    while (@ip_wan_field = $wan_collection->fetchrow_array()) { 
     my $ipAddr = @ip_wan_field[1]; 
     my $network = NetAddr::IP->new(@ip_wan_field[4], @ip_wan_field[5]); 
     my $ip  = NetAddr::IP->new($coreipAddr); 

     if ($ip->within($network) && $ip ne $ipAddr) { 
      print "$ip IS IN THE SAME subnet as $network \n"; 
     } 
     else { 
      print "$coreipAddr is outside the subnet for $network\n\n"; 
     } 
    } 
} 
+1

没有看到实际的查询,也没有数据库内容,这很难说。如果这是查询的完整内容,fetchrow_array将导致它退出。此外,这是一种非常低效的搜索方法,其响应顺序为n * m(n是从查询返回的m为wan_collection数的core_wan_field的数量。您可以通过将结果作为排序列表(无论是在数据库查询还是在perl中),并且按照n * log(n)+ m * log(m)搜索时间得到更多的结果。 –

+0

在这种情况下,当你遇到Perl问题时,确保你在脚本中使用'strict'和'use warnings'(实际上,确保你有它们)。我可以看到你没有启用警告,因为' perl'会建议你不要使用'@ip_wan_field [1]'这样的东西。 – scozy

回答

4

您的sql查询是单次传递操作。如果要多次循环第二个集合,则需要缓存这些值并对缓存进行交换,或重新运行查询。

我当然会建议你使用fetchall_arrayref

my $wan_arrayref = $wan_collection->fetchall_arrayref; 

while (my @ip_core_wan_field = $wan_core_collection->fetchrow_array()) { 
    my $coreipAddr = @ip_core_wan_field[1]; 

    for my $ip_wan_field_ref (@$wan_arrayref) { 
     my @ip_wan_field = @$ip_wan_field_ref; 

当然还有其他的方法来使这个操作更加高效与第一选项去,但是这是你的当前问题的症结所在。

+0

感谢您的帮助。我将sql查询添加到循环中,现在它正在做它需要做的事情。有点傻了,因为我做了一个假设,我只需要一次读取它,并将其存储在数组中。 – user3642981