Joel Plotkin
2015-03-24 15:45:18 UTC
Hi,
I have recently ported a large (1.4M line) perl application from:
Centos 6.6
DBI version 1.6.09
DBD::ODBC version 1.23
To:
Centos 6.6
DBI version 1.6.33
DBD::ODBC version 1.50 (and same issue with 1.50_4)
The error doesn't occur in the 1.23 version, only the later 1.50* versions.
This error occurs using MS SQL Server 2005, but I don't think it's db
server dependent.
The specific error occurs when one creates a statement handle in a
subroutine and returns the statement handle via a return value. Specific
test program attached. Sample code that generates error below:
************************************
#!/usr/bin/perl
use strict;
select((select(STDOUT), $|=1)[$[]);
package main;
BEGIN {
# Standard modules
use Carp;
use DBI;
};
my $dbh;
MAIN: {
# open data connection
my $attr = {};
my $odbc = "DBI:ODBC:XXXX_odbc";
my $db_nm="XXXXX";
my $db_user_nm="XXXXX";
my $db_user_passwd="XXXXX";
carp "opening new db connection\n";
$dbh = DBI->connect($odbc, $db_user_nm, $db_user_passwd, $attr) ||
carp "Error opening database";
my $trace_filename = "/tmp/dbi_trace.dat";
$dbh->trace(2, $trace_filename);
# run query
my $sql = "SELECT Name FROM Person WHERE p_id = 123";
* my ($sth) = &do_pexect($sql);*
my $rowcache = $sth->fetchall_arrayref();
#pop off all rows. destroys $rowcache structure.
while (my $row = shift @$rowcache) {
my ($last_nm) = @$row;
}
$sth->finish();
#
# Run same sql a 2nd time
#
# undef $sth;
* ($sth) = &do_pexect($sql);*
carp "This is a test 3\n";
$rowcache = $sth->fetchall_arrayref();
carp "This is a test 4\n";
#pop off all rows. destroys $rowcache structure
while (my $row = shift @$rowcache) {
my ($last_nm) = @$row;
}
$sth->finish();
undef $sth;
return;
}
sub do_pexect {
# input parameters
my($sql) = @_;
my $out;
$out = $dbh->prepare($sql) ||
carp "prepare ($sql): ".$dbh->errstr;
$out->execute() ||
carp "execute ($sql): ".$dbh->errstr;
return($out);
}
************************************
Basic trace error:
-> prepare for DBD::ODBC::db (DBI::db=HASH(0x13c8928)~0x1668428 '
SELECT name FROM Person WHERE p_id = 123') thr#139f010
<- prepare= DBI::st=HASH(0x156c370) at test12.pl line 92
-> execute for DBD::ODBC::st (DBI::st=HASH(0x156c370)~0x16e8898)
thr#139f010
<- execute= -1 at test12.pl line 95
-> DESTROY for DBD::ODBC::st (DBI::st=HASH(0x13c8c28)~INNER) thr#139f010
!! ERROR: 1 ' Unable to fetch information about the error' (err#1)
<- DESTROY= undef at test12.pl line 70
DBD::ODBC::st DESTROY failed: Unable to fetch information about the
error at test12.pl line 70.
This is a test 3
at test12.pl line 70.
main::joel_init() called at test12.pl line 36
!! The ERROR '1' was CLEARED by call to fetchall_arrayref method
***********************
The basic error is that when the handle is created the 2nd time in the
sub-routine, DBD destroys the original $sth attached to the $dbh. Then,
when the sub-routine finishes, perl auto-trash compactor tries to destroy
$sth a 2nd time as it's the left hand value of the equate statement:
($sth) = &do_pexec($sql); but this doesn't work as the $sth has already
been destroyed in the subroutine.
This trace/error didn't occur in the earlier versions of DBD but now do...
I can get rid of the error by doing: undef $sth; before the 2nd use of the
variable but this should not be necessary.
Has anyone else experienced this issue with the newer versions of DBD?
Thanks for any insight,
Joel
I have recently ported a large (1.4M line) perl application from:
Centos 6.6
DBI version 1.6.09
DBD::ODBC version 1.23
To:
Centos 6.6
DBI version 1.6.33
DBD::ODBC version 1.50 (and same issue with 1.50_4)
The error doesn't occur in the 1.23 version, only the later 1.50* versions.
This error occurs using MS SQL Server 2005, but I don't think it's db
server dependent.
The specific error occurs when one creates a statement handle in a
subroutine and returns the statement handle via a return value. Specific
test program attached. Sample code that generates error below:
************************************
#!/usr/bin/perl
use strict;
select((select(STDOUT), $|=1)[$[]);
package main;
BEGIN {
# Standard modules
use Carp;
use DBI;
};
my $dbh;
MAIN: {
# open data connection
my $attr = {};
my $odbc = "DBI:ODBC:XXXX_odbc";
my $db_nm="XXXXX";
my $db_user_nm="XXXXX";
my $db_user_passwd="XXXXX";
carp "opening new db connection\n";
$dbh = DBI->connect($odbc, $db_user_nm, $db_user_passwd, $attr) ||
carp "Error opening database";
my $trace_filename = "/tmp/dbi_trace.dat";
$dbh->trace(2, $trace_filename);
# run query
my $sql = "SELECT Name FROM Person WHERE p_id = 123";
* my ($sth) = &do_pexect($sql);*
my $rowcache = $sth->fetchall_arrayref();
#pop off all rows. destroys $rowcache structure.
while (my $row = shift @$rowcache) {
my ($last_nm) = @$row;
}
$sth->finish();
#
# Run same sql a 2nd time
#
# undef $sth;
* ($sth) = &do_pexect($sql);*
carp "This is a test 3\n";
$rowcache = $sth->fetchall_arrayref();
carp "This is a test 4\n";
#pop off all rows. destroys $rowcache structure
while (my $row = shift @$rowcache) {
my ($last_nm) = @$row;
}
$sth->finish();
undef $sth;
return;
}
sub do_pexect {
# input parameters
my($sql) = @_;
my $out;
$out = $dbh->prepare($sql) ||
carp "prepare ($sql): ".$dbh->errstr;
$out->execute() ||
carp "execute ($sql): ".$dbh->errstr;
return($out);
}
************************************
Basic trace error:
-> prepare for DBD::ODBC::db (DBI::db=HASH(0x13c8928)~0x1668428 '
SELECT name FROM Person WHERE p_id = 123') thr#139f010
<- prepare= DBI::st=HASH(0x156c370) at test12.pl line 92
-> execute for DBD::ODBC::st (DBI::st=HASH(0x156c370)~0x16e8898)
thr#139f010
<- execute= -1 at test12.pl line 95
-> DESTROY for DBD::ODBC::st (DBI::st=HASH(0x13c8c28)~INNER) thr#139f010
!! ERROR: 1 ' Unable to fetch information about the error' (err#1)
<- DESTROY= undef at test12.pl line 70
DBD::ODBC::st DESTROY failed: Unable to fetch information about the
error at test12.pl line 70.
This is a test 3
at test12.pl line 70.
main::joel_init() called at test12.pl line 36
!! The ERROR '1' was CLEARED by call to fetchall_arrayref method
***********************
The basic error is that when the handle is created the 2nd time in the
sub-routine, DBD destroys the original $sth attached to the $dbh. Then,
when the sub-routine finishes, perl auto-trash compactor tries to destroy
$sth a 2nd time as it's the left hand value of the equate statement:
($sth) = &do_pexec($sql); but this doesn't work as the $sth has already
been destroyed in the subroutine.
This trace/error didn't occur in the earlier versions of DBD but now do...
I can get rid of the error by doing: undef $sth; before the 2nd use of the
variable but this should not be necessary.
Has anyone else experienced this issue with the newer versions of DBD?
Thanks for any insight,
Joel