RaiseError causing unexpected behavior

Joel Stevenson <[email protected]>
Newsgroups gmane.comp.db.mysql.perl
Message-ID <p0621020dbe8eba137920@[192.168.0.9]>
Hi,

I'm running into a strange thing with the DBD-mysql driver.  It 
appears that when RaiseError is true that an error received on one 
statement handle is being propogated to another statement handle, 
despite having been caught in an eval{} block and also cleared (as 
seen in the DBI tracing output) via the next call to a fetchrow_* 
method.  Essentially what I have is one statment handle which gets 
fetchrow_hashref called on it in a while loop and within that while 
loop I have another statement handle which is trying to select from a 
table which may or may not exist.  Because of the uncertainty of the 
second handle's success I've wrapped it in an eval{} block to trap 
those cases when the table isn't there.  The eval does successfully 
trap the error, but for some reason at the end of the top while loop 
the last fetchrow_hashref call receives the last error which was 
delivered to the inner statement handle.

When I run this code (included at the end of this email) I get the 
following output (which includes the two rows retrieved in the while 
loop expression and the errors received for each statement inside 
that while loop):

<snip>

[srv1:~] me% perl db_test.pl
Retrieved: John
##ERR## DBD::mysql::st execute failed: Table 'test.table_not_exists' 
doesn't exist at db_test.pl line 25.
Retrieved: Frank
##ERR## DBD::mysql::st execute failed: Table 'test.table_not_exists' 
doesn't exist at db_test.pl line 25.
DBD::mysql::st fetchrow_hashref failed: Table 'test.table_not_exists' 
doesn't exist at db_test.pl line 19.

</snip>

In comparison when I run this code using DBD::Pg (because that's the 
other database and DBD driver I have installed) and a similar setup 
in PostgreSQL, I get the following output:

<snip>

[srv2:~] me% perl db_test.pl
Retrieved: John
##ERR## DBD::Pg::st execute failed: ERROR:  relation 
"table_not_exists" does not exist at db_test.pl line 25.
Retrieved: Frank
##ERR## DBD::Pg::st execute failed: ERROR:  relation 
"table_not_exists" does not exist at db_test.pl line 25.
db_test finishing up.
LAST: DBD::Pg::st execute failed: ERROR:  relation "table_not_exists" 
does not exist at db_test.pl line 25.

</snip>

The mysql run shows that the last two lines which should print 
"db_test finishing up" and the last error received are never executed 
because the fetchrow_hashref call in the while loop expression is 
receiving the 'test.table_not_exists' error (though that handle does 
not select from that table).

When setting the dbi tracing I can see that the 'table does not 
exist' error is being 'CLEARED by call to fetrow_hashref method' but 
then that error is being delivered on the final iteration of the 
while loop expression.

Here is the actual code:
#!/usr/bin/perl

use strict;
use warnings;

use DBI;

my $dbh = DBI->connect (
         "dbi:mysql:host=localhost;port=3306",
         'root',
         'flowers',
         {RaiseError => 1, PrintError => 0});

#$dbh->trace(4);

my $topSTH = $dbh->prepare ("SELECT name FROM test.table_exists");
$topSTH->execute ();

while (my $hRef = $topSTH->fetchrow_hashref ()) {

     print STDERR "Retrieved: ".$hRef->{name}."\n";

     eval {
         my $inSTH = $dbh->prepare ("SELECT foo FROM test.table_not_exists");
         $inSTH->execute ();
     };
     if ($@) {
         print STDERR "##ERR## $@";
     }

}

print STDERR "db_test finishing up.\n";
print STDERR "LAST: $@" if ($@);

__EOF__





Does anyone know what's happening here and/or how I can avoid this?

TIA,
Joel


-- 
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe:    http://lists.mysql.com/[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.