Helpful Information
 
 
Category: Perl Programming
for loop - MY LOGIC IS FLAWED

Can someone tell me what is wrong with my for looping? This script goes through a mysql database and checks the validity of each url. After all the urls have been checked it just keeps looping and DBI generates an error that says "fetchrow_array failed: fetch() without execute()" over and over. I think the problem has to do with my misunderstanding of the line $numrows = $sth->rows. Please help me, here is my code:

<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>
#!/usr/bin/perl

use LWP::UserAgent;
use DBI;

$db_database = "db";
$db_uid = "root";
$db_pwd = "password";
($ua = LWP::UserAgent->new)->timeout(20); #actually set timeout


$dbh = DBI->connect ("DBI:mysql:$db_database".$mysqlsock, $db_uid, $db_pwd) or die("could not connect to dbn");
$sth = $dbh->prepare("SELECT url FROM files");
$sth -> execute();
$numrows = $sth->rows;

print "nn";
for ($i = 0; $i = $numrows; ++$i) {
$url = ($sth->fetchrow_array);

if(($ua->request(HTTP::Request->new('HEAD', $url)))->is_success()) {
$validity = "link works";
} else {
$validity = "link sucks";
$valid_update = $dbh->do("UPDATE files SET valid = valid + 1 WHERE url = '$url'");
}
print "$validityn$urlnn";
}
[/code]

well, i'm not exactly the best with Perl, but i noticed a couple things off the bat.

i think that this:
<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>for ($i = 0; $i = $numrows; ++$i) {[/code]
should be this:
<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>for ($i = 0; $i = $numrows; $i++) {[/code]

secondly, i think that you can't define the '$i' twice (or rather, it needs not be and therefore could be posing a problem), as it sort of poses a conflict of interest. so further, you may want to change it to this:
<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>for ($i; $i = $numrows; $i++) {[/code]

and as a suggestion (an unnecessary change, though), you might want to squeeze that together, as Perl will output it better. so further:
<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>for ($i;$i=$numrows;$i++) {[/code]


i hope this could help!


Cujo




[This message has been edited by CujoRbd (edited September 25, 2000).]

Keep in mind that a for loop can be equivacated to a while loop:

for ($i=0;$i<$numrows;$i++)
{
// code
}

is the same as:
$i=0;
while ($i<$numrows)
{
// code
$i++;
}

so you see, the for loop also has a conditional statement, in the code you posted it is $i=$numrows, which is where your problem is. "=" is an assignment operator, and because $i can be assigned to $numrows, the operation returns true, so your conditonal is always true. You need to use a comparison operator, such as "==" or "<=" which will at some point return false and cease the execution of your loop. Incedentally,
$i=0;
$a=++$i; // $a=1, $i=1
$a=$i++ // $a=0; $i=1

So i don't think this will have a huge effect on your loop.

<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">quote:</font><HR>Originally posted by scream:
Can someone tell me what is wrong with my for looping?
<BLOCKQUOTE><font size="1" face="Verdana,Arial,Helvetica">code:</font><HR><pre>
for ($i = 0; $i = $numrows; ++$i) {
$url = ($sth->fetchrow_array);
...
}
[/code][/quote]


If you have no need for the count of rows that are returned you can just use this while loop, it will keep returning rows until there are no more left.

while (my $url = $sth->fetchrow) {
#process $url here
}

You don't need to use fetchrow_array if the row you are returning consists of just one field.

Don










privacy (GDPR)