Perl crashes when script exits after closing database connection

1

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.

windows
perl
odbc
dbi
asked on Stack Overflow May 14, 2020 by Coxy • edited May 14, 2020 by Coxy

2 Answers

-1

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.

answered on Stack Overflow May 14, 2020 by Georg Mavridis
-1

$$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")
answered on Stack Overflow May 14, 2020 by Marcell Dbc • edited May 14, 2020 by Marcell Dbc

User contributions licensed under CC BY-SA 3.0