[freetds] freetds-0.63: Problem with DBD::ODBC
Daniel Kasak
dkasak at nusconsulting.com.au
Mon Jan 9 20:06:26 EST 2006
Hi all.
I've just noticed that some code that was working under freetds-0.62.4
is no longer working under freetds-0.63.
I'm using:
Perl 5.8.7
DBD::ODBC-1.13
The code that is failing is a simple prepare statement, in the form:
---
eval {
my $sth = $dbh->prepare( "insert into SomeTable ( Field_1, Field_2,
Field_3 ) values ( ?, ?, ? )
|| die $dbh->errstr;
};
if ( $@ ) {
print "Couldn't prepare statement ... DB server said: $@\n";
# more error handling code
}
---
The prepare statement dies, but doesn't give a useful ( ie SQL related )
error message ... it simply says 'prepare failed', and the line number.
This *could* be related to me running a sequence of insert statements
without calling $sth->finish or $dbh->disconnect between each one. I
remember I had problems with this sort of thing before, but the code in
question ( about 8 inserts in sequence ) still works under freetds-0.62.4.
Has anyone else had problems of this sort? In particular, it looks like
DBD::ODBC is failing when creating a new statement handle.
I've got details below for those who are interested - I had a half-arsed
attempt at finding out what's going on, but I'm no Perl guru, and I'm
pretty sure that the problem lies in freetds instead of in DBI / DBD::ODBC.
When I use a debugger to follow what's happening, I first enter
DBD::ODBC's prepare() method, which looks like:
---
sub prepare {
my($dbh, $statement, @attribs)= @_;
# create a 'blank' dbh
my $sth = DBI::_new_sth($dbh, {
'Statement' => $statement,
});
# Call ODBC func in ODBC.xs file.
# (This will actually also call SQLPrepare for you.)
# and populate internal handle data.
DBD::ODBC::st::_prepare($sth, $statement, @attribs)
or return undef;
$sth;
}
---
The part that create's a 'blank' dbh is the part that's failing. It in
turn calls DBI's _new_sth method:
---
sub _new_sth { # called by DBD::<drivername>::db::prepare)
my ($dbh, $attr, $imp_data) = @_;
my $imp_class = $dbh->{ImplementorClass}
or Carp::croak("DBI _new_sth: $dbh has no ImplementorClass");
substr($imp_class,-4,4) = '::st';
my $app_class = ref $dbh;
substr($app_class,-4,4) = '::st';
_new_handle($app_class, $dbh, $attr, $imp_data, $imp_class);
}
---
Everything *seems* OK to me, and the last line enters DBI's _new_handle
method:
---
sub _new_handle {
my ($class, $parent, $attr, $imp_data, $imp_class) = @_;
Carp::croak('Usage: DBI::_new_handle'
.'($class_name, parent_handle, \%attr, $imp_data)'."\n"
.'got: ('.join(", ",$class, $parent, $attr, $imp_data).")\n")
unless (@_ == 5 and (!$parent or ref $parent)
and ref $attr eq 'HASH'
and $imp_class);
$attr->{ImplementorClass} = $imp_class
or Carp::croak("_new_handle($class): 'ImplementorClass' attribute
not given");
DBI->trace_msg(" New $class (for $imp_class, parent=$parent,
id=".($imp_data||'').")\n")
if $DBI::dbi_debug >= 3;
# This is how we create a DBI style Object:
my (%hash, $i, $h);
$i = tie %hash, $class, $attr; # ref to inner hash (for driver)
$h = bless \%hash, $class; # ref to outer hash (for application)
# The above tie and bless may migrate down into _setup_handle()...
# Now add magic so DBI method dispatch works
DBI::_setup_handle($h, $imp_class, $parent, $imp_data);
return $h unless wantarray;
($h, $i);
}
---
Everything *looks* OK to me until I get to:
$h = bless \%hash, $class;
At this point, my debugger is telling me that there's a problem with
%hash ( don't have the exact error now, but I'll get it if someone wants
it ).
--
Daniel Kasak
IT Developer
NUS Consulting Group
Level 5, 77 Pacific Highway
North Sydney, NSW, Australia 2060
T: (+61) 2 9922-7676 / F: (+61) 2 9922 7989
email: dkasak at nusconsulting.com.au
website: http://www.nusconsulting.com.au
More information about the FreeTDS
mailing list