On Mon, Feb 26, 2007 at 10:29:37AM +0000, Martin Evans wrote:
> Tim Bunce wrote:
> 
> >Alternatively you could try doing the same thing after calling prepare:
> >
> >    $sth = $dbh->prepare(...);
> >    $sth->{Err} = \my $err;
> >    $sth->{Errstr} = \my $errstr;
> >    $sth->{State} = \my $state;
> >
> >but I've not tried that and there's a chance it won't work.
> 
> It doesn't:
> 
> "Can't set DBI::st=HASH(0x8c78ffc)->{Err}: unrecognised attribute name or 
> invalid value" * 3

You can get round that:

    my $sth_inner = tied %$sth;
    $sth_inner->{Err} = \my $err;
    $sth_inner->{Errstr} = \my $errstr;
    $sth_inner->{State} = \my $state;

but it's breaking encapsulation, so don't tell anyone I said so ;-)
And there's still a chance it won't work.

> >Also, be aware that there may be subtle issues where code expects the
> >dbh to reflect the error status of the last child sth call.
> >
> >For example, when the $dbh->do() method is returning through the DBI
> >dispatcher with RaiseError/PrintError enabled, the DBI checks the $dbh
> >for an error. But for most drivers the error would not have happened on
> >the dbh itself, but on a child sth. In this case you might be okay
> >because the sth should have been DESTROYed by then and the DBI copies
> >up the error status from the sth to the dbh on DESTROY, but you're
> >relying on the timing of the DESTROY call - and I recall that some
> >(older) versions of perl could delay the call beyond do() returning.
> >
> >That's just one example. There may be others.
> 
> That is the only one I've found so far - with perl 5.8.8 and DBI 1.54 
> and DBD::Oracle 1.19.

Perhaps a better approach would be to have set_err explicitly copy the
err/errstr/state to the parent handle. That should work for drivers
using set_err to record errors - which all should be by now.
(That's DBIh_SET_ERR_SV / DBIh_SET_ERR_CHAR for drivers written in C.)

> The only method that reliably works now is one of your earlier 
> suggestions which is to store the values and use set_err to put them 
> back later (I disable HandleError/HandleSetError during the restore).
> 
> Thanks for all the help.

No problem Martin.

Tim.

Reply via email to