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.

Reply via email to