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.