I have a Perl script that opens a ODBC connection to an Oracle database using DBI. Some data is selected, some work is done, no data is actually committed back to the database but I can't tell whether that makes any difference.
In the END
block of the script the database is disconnected.
END
{
$$db->disconnect() if defined $$db;
exit 0;
}
Instead of exiting, perl.exe will crash with a fault in an Oracle DLL.
Faulting application name: perl.exe, version: 0.0.0.0, time stamp: 0x5407ac11
Faulting module name: OraOCIICUS19.dll_unloaded, version: 19.6.0.0, time stamp: 0x5e1181b2
Exception code: 0xc0000005
Fault offset: 0x0000000000df18b0
I tried adding a commit()
method call before disconnect()
ing but that didn't help.
Edit1: $$db
is used throughout the script when calling a method on the object. I assume this is because the DBI connection is created within a module method.
my $db = MyModule::OpenDB();
my ( $foo, $bar ) = MyModule::GetFoo( $db );
my $rows = $$db->selectall_arrayref( $SQLStr, { Slice => {} } );
If I try to call a method on a single$ then I get the error Can't call method "commit" on unblessed reference
Edit2: the module that opens the DBI connection does so thusly:
sub OpenDB
{
my ($params) = @_;
my $db = DBI->connect( "dbi:ODBC:Driver={Oracle in instantclient_19_6};Dbq=MYDB", "MYUSER", "MYPASS", {AutoCommit => 0, RaiseError => 1, PrintError => 0, ShowErrorStatement => 1 } ) or croak $DBI::errstr;
$db->{LongReadLen} = 20480;
$db->{LongTruncOk} = 1;
return \$db;
}
I have already tried toggling AutoCommit
on and off in case that was the source of any weirdness.
You don't need to disconnect the DB on script-exiting. Perl (DBI) will do this automatically for you when DB-handle gets out of scope.
Usually (if $db is an "un-weakend" reference to the $dbh-handle) this shouldn't have happened before so doing this should not throw any errors, but my guess is that the error stems from some other part of your code.
Anyway - removing the disconnect in the end-block is safe.
$$db is used throughout the script when calling a method on the object. I assume this is because the DBI connection is created within a module method.
Hi,
mhh, if youre really using DBI you maybe should take a look on your module. thats how I do that:
sub mysql_connect($$$$) {
my ($f_database, $f_host, $f_user, $f_password) = (shift, shift, shift, shift);
my $f_handler = DBI->connect("DBI:mysql:database=$f_database;host=$f_host", $f_user, $f_password, {RaiseError=>0,PrintError=>1});
return $f_handler;
};
my $dbh = mysql_connect($db, $host, $user, $pass);
my $sql = "SELECT X FROM Y.Z";
my $stmt = $dbh->prepare($sql);
my $response = $stmt->execute();
while(my $rowref = $stmt->fetchrow_hashref()){
my %row = %$rowref;
for(keys %row){
print $_." => ".$row{$_}."\n";
}
}
$dbh->disconnect();
EDIT: Try it out, but change mysql to oracle:
connect('DBI:Oracle:XE',"us01","us01")
User contributions licensed under CC BY-SA 3.0