On Tue, Jan 23, 2007 at 11:28:42AM +0000, Martin Evans wrote:
> From the DBI pod under "METHODS COMMON TO ALL HANDLES" for "err:
>
> "The DBI resets $h->err to undef before almost all DBI method calls, so
> the value only has a short lifespan. Also, for most drivers, the
> statement handles share the same error variable as the parent database
> handle, so calling a method on one handle may reset the error on the
> related handles."
>
> Given the "most drivers" above I presume some drivers don't share the
> error variable for database and statement handles. Which are these
> drivers? If you don't know of any, perhaps you can tell me how to find
> out whether they do?
I can't dictate what driver authors do, I can just try to make it easy
to do the right thing. Of course 'the right thing' may change over time.
> I did find the following in DBI.pm:
>
> sub _new_drh { # called by DBD::<drivername>::driver()
> my ($class, $initial_attr, $imp_data) = @_;
> # Provide default storage for State,Err and Errstr.
> # Note that these are shared by all child handles by default! XXX
> # State must be undef to get automatic faking in DBI::var::FETCH
> my ($h_state_store, $h_err_store, $h_errstr_store) = (undef, 0, '');
It used to be that those were shared by all dbh, but that got fixed
back in Feb 2003. The Changes file has this note for DBI 1.33:
Database handles no longer inherit shared $h->err/errstr/state storage
from their drivers, so each $dbh has it's own $h->err etc. values
and is no longer affected by calls made on other dbh's.
Now when a dbh is destroyed it's err/errstr/state values are copied
up to the driver so checking $DBI::errstr still works as expected.
FYI part of the fix is in _new_dbh, which provides new storage for the handle:
...
$attr->{Err} ||= \my $err;
$attr->{Errstr} ||= \my $errstr;
$attr->{State} ||= \my $state;
_new_handle($app_class, $drh, $attr, $imp_data, $imp_class);
...
> The reason I'd like to know is that I have some circumstances where an
> error occurs on a statement handle which goes out of scope immediately
> so err is not available. I notice the connection handle (with
> DBD::Oracle) also contains the same error number/string and this would
> be great except for the fact we use multiple DBDs.
That's the right thing to happen and I'd be very surprised if that
didn't happen for all DBDs. But of course I can't guarantee it.
Check that when the driver calls _new_dbh it's not passing in
Err/Errstr/State attributes. Or if it is, that they're private
ref and not shared by other dbh.
Tim.