Strange bind_param issue

"Martin J. Evans" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.sybase.devel
Organization Easysoft Limited
Message-ID <[email protected]>
I've just been given an rt https://rt.cpan.org/Ticket/Display.html?id=78838 and am at a loss to explain exactly what is happening. I wonder if anyone can help?

Some background:

DBI says for bind_param:

"The bind_param method takes a copy of $bind_value and associates it (binds it) with a placeholder"

As far as I am aware DBD::ODBC does not copy the scalar given to it - so perhaps DBI does this. The problem I'm seeing in the provided example is the pointer passed to ODBC's SQLBindParameter at the time bind_param is called no longer points to a valid string when execute is called. However, changing the call to bind_param to pass $obj as "$obj" appears to fix the problem. Can anyone say if DBD::ODBC should work with either example and explain what might be happening here:

use DBI;
my $dbh =
DBI->connect("dbi:ODBC:DSN=xxx;UID=xx;PWD=yy;MARS_Connection=No;");
my $obj = new Object();
my $sql = q(SELECT ? AS result);
my $sth = $dbh->prepare($sql);

# interesting - is the following use of $obj really as a string?
# in the call to bind_param here, DBD::ODBC binds the pv ptr of the scalar
# it is given in a SQLBindParameter call but by the time execute is called
# the string at that address is no longer valid. I kind of expect that as
# what to_s returns is only required in the bind_param statement and yet
# DBI says "bind_param takes a copy".
# However if the following is changed to "$obj" it works
$sth->bind_param(1, $obj);
$sth->execute();

while (my $row = $sth->fetchrow_hashref()) {
   print $row->{'result'}, "\n";
}

package Object;
use overload '""' => 'to_s';
sub new() { bless { }, shift };
sub to_s() { my $self = shift; ref($self); }

Output when using $obj:

value passed to DBD::ODBC's bind_param = "Object"
pointer at execute time seems to point to rubbish
output of script: 8�k�8

When "$obj" passed to bind_param

value passed to DBD::ODBC's bind_param = "Object"
pointer at execute time points to "Object"
output of script: Object

As a quick test I did the following and it seems to work so I guess there is something about the above Perl I don't get.

use DBI;
use strict;
use warnings;
use Data::Dumper;
my $h = DBI->connect('dbi:ODBC:baugi','sa','easysoft', {RaiseError => 1});
eval {
     $h->do(q/drop table mje/);
};
$h->do(q/create table mje (a int)/);
my $s = $h->prepare(q/insert into mje values(?)/);
{
     my $a = 99;
     $s->bind_param(1, $a);
     $a = 66;
}
$s->execute;
print Dumper($h->selectall_arrayref(q/select * from mje/));

outputs:

$VAR1 = [
           [
             99
           ]
         ];

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.