Reputation: 59456
I have a Perl script like this:
use DBI;
eval {
my $dbh = DBI->connect("dbi:Oracle:<database>", "<user>", "<password>") or die ($DBI::errstr);
my $sth = $dbh->prepare("INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (?,?)");
$sth->execute( "foo", "bar" ) or die($dbh->errstr);
$dbh->disconnect;
};
my $err = $@;
print "\$err => $err\n";
When I run it the console produce following output:
DBD::Oracle::st execute failed: ORA-01722: invalid number (DBD ERROR: error possibly near <*> indicator at char 53 in 'INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (:<*>p1,:p2)') [for Statement "INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (?,?)" with ParamValues: :p1='foo', :p2='bar'] at C:\Temp\Perl-1.pl line 6.
$err => ORA-01722: invalid number (DBD ERROR: error possibly near <*> indicator at char 53 in 'INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (:<*>p1,:p2)') at C:\Temp\Perl-1.pl line 6.
I would like to store the full error message, but variable $err
contains only ORA-01722: invalid number (DBD ERROR: error possibly near <*> indicator at char 53 in 'INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (:<*>p1,:p2)') at C:\Temp\Perl-1.pl line 6.
But I would like to get also [for Statement "INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (?,?)" with ParamValues: :p1='foo', :p2='bar']
which is missing.
Any idea how to catch this additional information?
Upvotes: 3
Views: 2277
Reputation: 1110
Take a look at the documentation for the PrintError attribute. It's enabled by default and is why the error is being logged to the console. It's also the source of the DBD::Oracle::st execute failed:
prefix.
Then take a look at the ShowErrorStatement attribute. It's also enabled by default (in DBD::Oracle but not all drivers) and is the source of the [for Statement "..." with ParamValues: :p1='foo', :p2='bar']
suffix.
Then take a look at the RaiseError attribute. If that was set then the DBI would throw an exception (containing the message you saw logged to the console) when the error occurs. You could catch that exception and handle it however you want.
In general, I strongly recommend that all applications using the DBI enable RaiseError. It makes your applications more robust and you life much easier.
p.s. For advanced use-cases you might want to use look into the HandleError attribute, or in very rare cases, the HandleSetError attribute.
Upvotes: 4
Reputation: 59456
Based on given comments and answer I found these solutions:
use DBI;
local $SIG{__WARN__} = sub {
my $err = shift;
print "\$err => $err\n";
};
my $dbh = DBI->connect("dbi:Oracle:<database>", "<user>", "<password>", { PrintError => 1, ShowErrorStatement => 1 } );
my $sth = $dbh->prepare("INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (?,?)");
$sth->execute( "foo", "bar" );
$dbh->disconnect;
and
use DBI;
eval {
my $dbh = DBI->connect("dbi:Oracle:<database>", "<user>", "<password>", { RaiseError => 1} );
my $sth = $dbh->prepare("INSERT INTO WT_APPCERT_LH (STATUS, APPCERT) VALUES (?,?)");
$sth->execute( "foo", "bar" );
$dbh->disconnect;
};
my $err = $@;
print "\$err =>\n$err\n";
Upvotes: 0