Tim Bunce wrote: > On Tue, Aug 04, 2009 at 04:13:19PM +0100, Martin Evans wrote: >> Tim Bunce wrote: >>> On Tue, Aug 04, 2009 at 01:19:43PM +0100, Martin Evans wrote: >>>> This is my second attempt to try and get some insight into how to do >>>> this. The DBD::ODBC::ping method calls DBI::_new_sth to obtain a new >>>> statement handle but DBD::ODBC prevents creating a new statement handle >>>> when not connected (you cannot actually get one even if you wanted). The >>>> problem is once DBD::ODBC discovers we are not connected it does: >>>> >>>> DBIh_SET_ERR_CHAR( >>>> h, imp_xxh, Nullch, 1, >>>> "Cannot allocate statement when disconnected from the database", >>>> "08003", Nullch); >>>> >>>> and because PrintError is on the error is output and because RaiseError >>>> is on the error handler is called. Most people are calling ping when not >>>> connected and do not want this error and I wanted to mask it by >>>> temporarily disabling PrintError and RaiseError but it does not seem to >>>> work for me. >>>> >>>> Initially I tried using local $dbh->{PrintError} = 0 but this did not >>>> work. Then I remembered I needed to call STORE from inside the driver so >>>> changed to $dbh->STORE('PrintError', 0); but that does not work either. >>> That should work. Try calling $dbh->dump_handle after (and after doing >>> the same for RaiseError) that to see what the state of the handle is. >>> >>> Tim. >>> >>> p.s. You could also try using the HandleError attribute, but the above >>> should >>> work so let's find out what's happening there first. >> Thanks for the help Tim. >> >> Ignoring RaiseError for now as I'm imagining it will work (once it >> works) the same as PrintError. The ping sub is currently: >> >> sub ping { >> my $dbh = shift; >> my $state = undef; >> >> my ($catalog, $schema, $table, $type); >> >> $catalog = q{}; >> $schema = q{}; >> $table = 'NOXXTABLE'; >> $type = q{}; >> >> print "PrintError=", $dbh->FETCH('PrintError'), "\n"; >> my $pe = $dbh->FETCH('PrintError'); >> $dbh->STORE('PrintError', 0); >> $dbh->dump_handle; >> my $evalret = eval { >> # create a "blank" statement handle >> my $sth = DBI::_new_sth($dbh, { 'Statement' => "SQLTables_PING" }) >> or return 1; >> >> DBD::ODBC::st::_tables($dbh,$sth, $catalog, $schema, $table, $type) >> or return 1; >> $sth->finish; >> return 0; >> }; >> $dbh->STORE('PrintError', $pe); >> if ($evalret == 0) { >> return 1; >> } else { >> return 0; >> } >> } >> >> and the following perl and output are observed: >> >> perl -Iblib/lib -Iblib/arch -le 'use DBI;$h = DBI->connect();print >> "ping=",$h->ping(),"\n";$h->disconnect; print "ping=",$h->ping(), "\n";' >> PrintError=1 >> >> DBI::dump_handle (dbh 0x82c382c, com 0x82c4560, imp DBD::ODBC::db): >> FLAGS 0x100217: COMSET IMPSET Active Warn PrintWarn AutoCommit >> ERR '' >> ERRSTR '[unixODBC][Easysoft][SQL Server Driver][SQL >> Server]Changed language setting to us_english. (SQL-01000) >> [unixODBC][Easysoft][SQL Server Driver][SQL Server]Changed database >> context to 'master'. (SQL-01000)' >> PARENT DBI::dr=HASH(0x82bc5e0) >> KIDS 0 (0 Active) >> Name 'baugi' >> ping=1 >> >> PrintError=1 >> >> DBI::dump_handle (dbh 0x82c382c, com 0x82c4560, imp DBD::ODBC::db): >> FLAGS 0x100213: COMSET IMPSET Warn PrintWarn AutoCommit >> PARENT DBI::dr=HASH(0x82bc5e0) >> KIDS 0 (0 Active) >> Name 'baugi' >> DBD::ODBC::db ping failed: Cannot allocate statement when disconnected >> from the database at -e line 1. >> ping=0 >> >> I don't know if it is anything of a clue but if I fail to restore >> PrintError with STORE at the end of ping, the error is not seen in the >> second call to ping). > > Ah! The DBI is reporting the error information that's stored in the > handle when the ping method *returns*. > > You need to use $h->set_err(...) to clear the error state before > returning. > > Tim. > >
When I add $dbh->set_err(undef,'',''); it does clear the error. BTW, I saw the following in Gofer.pm at the start of ping: sub ping { my $dbh = shift; return $dbh->set_err(0, "can't ping while not connected") # warning unless $dbh->SUPER::FETCH('Active'); That did not work for me to generate a warning, even when I changed the 0 to "0" which is what I thought you did for a warning (http://search.cpan.org/~timb/DBI-1.609/DBI.pm#set_err). Martin -- Martin J. Evans Easysoft Limited http://www.easysoft.com