o2bwise has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

This is for something at work which folks are anxiously waiting on!

I am using the perl DBI mod and in that mod, in this portion:

while ( $sth->fetch() ) { .... }


I want to break out of the while loop if a condition is met and the condition is very basic. If the string begins with "foo", I want the bloody thing to end and I am ~99% sure, it is not ending when the condition occurs (and the condition does occur).

I have:

while ( $sth->fetch() ) { chomp $x; last if ( $x =~ /^foo/ ); } print "$x\n";


It is printing everything, not just strings that begin with "foo." Might someone be able to volunteer why this is not working and what I need to do to get it to work?

Thank you...

Tony

Replies are listed 'Best First'.
Re: getting out of a loop
by eric256 (Parson) on Jun 16, 2006 at 19:57 UTC

    It is hard to tell from that. Assuming you've somehow bound $x to $sth, you are printing it outside the loop not inside. The last is going to break out of the loop and goto the print statment, but $x is still defined so it will be printed.

    while ( $sth->fetch() ) { chomp $x; last if ( $x =~ /^foo/ ); print "$x\n"; }

    More importantly though. Why arn't you letting your DB pull out the ones that start with foo and get rid of them?


    ___________
    Eric Hodges
      Thanks, Eric.

      Looks like we're getting into Perl DBI Mod stuff I am ignorant about. I do have the following command, just above the while loop:

      $sth->bind_columns(\$x);
      I take it, $x is "bound" and this is the reason?

      Is there a way out of this?

      The reason I haven't matched to the pattern within the sql is because I only need to see one occurrence of this in order to know what I need to know - and there may be thousands.

      I just thought it was more efficient programming to identify the first occurrence it saw and then to proceed to the other things the code needs to accomplish.

      Is there a way to work around this binding feature of the Perl DBI? (I don't know anything about it, I just adhere to the syntax for satisfying queries and such.)

      Thanks!

      Tony

        Actualy you are probably still better off putting it in your SQL. Most database servers have an exists keyword, or if the value you are querying on is keyed then it will be VERY fast.

        Either way you don't want to leave the loop when it happens and then do what you want. Because then you don't know if you left the loop because you hit the end or because you found what you where looking for. If you want to use the loop, execute specific code if you find a match, then stop looking at the results you want the following:

        while ( $sth->fetch() ) { chomp $x; if ( $x =~ /^foo/ ) { print "$x\n"; last; } }

        Keep in mind that the database is still retrieving all the results so this is probably not as good as letting the DB handle the comparison.

        my ($count) = $dbh->selectrow_array("SELECT count(*) FROM table WHERE +LEFT(colum,3) = 'foo'"); if ($count > 0) { print "Do what you need here"; }

        ___________
        Eric Hodges
        You might want to take a look at DBIx::Simple (plus the optional supporting libraries it can make use of). This way you can avoid some of the dirty internal details that are biting you right now.