On 1/23/07, Martin Evans <[EMAIL PROTECTED]> wrote:
Thanks Jonathan, Jonathan Leffler wrote: > DBD::Informix is careful about errors. I would hope all DBDs are ;-) > Each statement handle keeps a copy of its most recent status/error > information out of the global sqlca variable (plus the sqlstate variable). > Each database handle has a copy of the most recently executed statement's > error/status information. Of course, this is made more complex by > AutoCommit which requires extra statements to be executed to simulate the > AutoCommit; you have to ignore the status of the extra statements when they > succeed, but record the error if they fail.
The 'you' in "you have to ignore" is 'the writer of DBD::Informix', not the programmer using DBD::Informix. Sorry if that misled you. So, I think you are saying that if you executed the following with
DBD::Informix: my $dbh = DBI->connect({RaiseError=>1}); eval { $dbh->begin_work; my $sth = $dbh->prepare(q/insert into table values (1)/); $sth->execute; # execute fails - say duplicate key error $dbh->commit; }; $dbh->err here would be what $sth->err was above in the eval after the execute (assuming you could have looked at $sth->err which you can't in this case because RaiseError was set).
Yes? No. $dbh->err would reflect the last statement executed on the $dbh - that is, the commit, unless the prepare or execute (or begin_work) raised an error, in which case it would reflect that error. To demonstrate what I was referring to, consider this context: my $st1 = $dbh->prepare("..."); my $st2 = $dbh->prepare("..."); $dbh->do('...'); # $dbh->err reflects the 'do' $st1->execute; # $st1->err reflects the execute; so does $dbh->err $st2->execute; # $st2->err reflects the second execute; so does $dbh->err; but $st1->err hasn't changed. $dbh->do('...'); # $dbh->err reflects the second 'do', but neither $st1->err nor $st2->err has been affected. The AutoCommit stuff I mentioned is related to the implicit begin work before the statement and implicit commit work after the statement that achieve the effect of AutoCommit in a database that doesn't auto-commit anyway. (I'll go into the gory details if you want - but only after you've read the DBD::Informix documentation and have questions arising.)
On 1/23/07, Martin Evans <[EMAIL PROTECTED]> 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 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, ''); >> >> 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.
-- Jonathan Leffler <[EMAIL PROTECTED]> #include <disclaimer.h> Guardian of DBD::Informix - v2005.02 - http://dbi.perl.org "I don't suffer from insanity - I enjoy every minute of it."