Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

$DBI::errstr is always undef

by spivey3587 (Acolyte)
on Mar 02, 2007 at 21:49 UTC ( #602967=perlquestion: print w/replies, xml ) Need Help??
spivey3587 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

We recently upgraded DBD::Oracle to 1.16 (from 1.12) and since then it seems that $DBI::errstr is never set. This happens on any error such as a prepare, execute, or connection error. Has anyone heard of a bug with this specific version? I saw nothing in the version change log. I didn't personally do the upgrade, but I didn't read that there are special switches needed during installation to turn this on. We're running perl 5.6.2, DBI 1.35, and Oracle 10g in a pool of linux servers.

Code like this no longer produces the expected results saying that the column is invalid:

my $dbh = DBI->connect( "dbi:Oracle:$database", $user, $passwd, {AutoC +ommit => 0, RaiseError => 1, PrintError => 0}) || die "Can't connect +to database: $DBI::errstr"; my $qry = $dbh->prepare(q{ select BAD__column from users where id=1254 +3256 }) or die "Prepare bad: $DBI::errstr"; ------OUTPUT------ Use of uninitialized value in concatenation (.) or string at ./dbitest line 15. Prepare bad: at ./ line 15. ------END--------

I see lots of indicators that $DBI::errstr is undef, mainly the -w switch output about using an uninit'd value. I've also seen errstr=undef when I turn DBI->trace on. Has anyone heard of this issue or know of a work-around? I've tried every trapping mechanism I know of, but none work indicating that it must be a lower-level issue with our DBD::Oracle upgrade (and because it works fine on other machines that were left on DBD 1.12).

Thanks! -Darin

Replies are listed 'Best First'.
Re: $DBI::errstr is always undef
by Joost (Canon) on Mar 02, 2007 at 22:05 UTC
    This looks like a bug in your DBD::Oracle but in any case you shouldn't be using RaiseError if you plan on testing the return codes.

    Setting RaiseError as you do will cause an exception to be thrown on all errors (except I think errors during the connect() call). That means that $dbh->prepare should either throw an exception or return a valid statement handle.

    Also, testing with mysql throws an error only when you execute the query object. Oracle might behave differently ofcourse:

    use strict; use warnings; use DBI; my $dbh = DBI->connect( "dbi:mysql:test", "root", "", {AutoCommit => 0 +, RaiseError => 1, PrintError => 0}) || die "Can't connect to databas +e: $DBI::errstr"; my $qry = $dbh->prepare(q{ select BAD__column from users where id=1254 +3256 }) or die "Prepare bad: $DBI::errstr"; $qry->execute();
    DBD::mysql::st execute failed: Table 'test.users' doesn't exist at tes line 8. Issuing rollback() for database handle being DESTROY'd without explici +t disconnect().
      MySQL doesn't really have a separate prepare phase, so it doesn't parse the statement until you execute it. I would expect setting RaiseError to cause Oracle to throw an error during prepare though.
Re: $DBI::errstr is always undef
by jettero (Monsignor) on Mar 02, 2007 at 22:01 UTC

    I suspect you want  die "couldn't connect!!!: " . DBI->errstr not $DBI::errstr. That is, it's a function, not a string. use strict doesn't catch those when you change namespace like that. Although, the documentation for DBI clearly shows $DBI::errstr, so who knows. Personally, I use the function and don't get any warnings.

    UPDATE: ikegami, yes, I said that the example shows $DBI::errstr. No need to point it out again. What I was saying is that using the function also works and avoids the warning. In fact the function really just returns the scalar, so it's a silly thing to argue about anyway.

    And if you're curious, they haven't updated the docs yet, but there's been a todo item about it for like 8 years:

    # Help people doing DBI->errstr, might even document it one day # XXX probably best moved to cheaper XS code sub err { $DBI::err } sub errstr { $DBI::errstr }


      According to the docs, $DBI::errstr is a "dynamic attribute", "always associated with the last handle used", and is "Equivalent to $h->errstr." The example in the documentation for connect even uses $DBI::errstr, not DBI->errstr.

      Jettero, that's it! The documentation is wrong. I have been going crazy tonight trying to track this down. A bit of googling will reveal that hundreds of people have suffered the same problem. This needs to be a priority to fix it. By the way, I'm using DBD::mysql and it's just the same.

        I don't think the documentation is wrong at all. There may be something wrong with DBD::mysql in your case and perhaps with DBD::Oracle in the past but for DBD::ODBC and DBD::Oracle now

        perl -le 'use strict; use warnings;use DBI; my $h = DBI->connect("dbi: +ODBC:does_not_exist", undef, undef, {PrintError => 0, RaiseError => 0 +}) or die $DBI::errstr;' [unixODBC][Driver Manager]Data source name not found, and no default d +river specified (SQL-IM002) at -e line 1.
        perl -le 'use strict; use warnings; use DBI; my $h = DBI->connect("dbi;sid=fred", "xxx","yyy", {RaiseError => +0, PrintError => 0}) or die $DBI::errstr;' ORA-24327: need explicit attach before authenticating a user (DBD ERRO +R: OCISessionBegin) at -e line 1.
        they both seem to work fine for me. Interestingly, every time (except for the OP in this thread) I see this mentioned these days it is DBD::mysql. However, for me even DBD::mysql works fine:
        perl -le 'use strict; use warnings; use DBI; my $h = DBI->connect("dbi +:mysql:database=testd", "xxx","yyy", {RaiseError => 0, PrintError => +0}) or die $DBI::errstr;' Unknown database 'testd' at -e line 1.

        I'm using all the latest released DBDs and DBI.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://602967]
Approved by Joost
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2018-05-21 10:05 GMT
Find Nodes?
    Voting Booth?