Subject: | bind_param does not correctly stringify blessed objects when connected to MS SQL Server |
When using DBD::ODBC to connect to a Microsoft SQL Server database (via
the Easysoft ODBC driver on Linux), the bind_param() method doesn't seem
to properly stringify blessed objects.
This was the behavior in version 1.23 and seems to have changed in 1.24,
and kept that behavior through to (and including) 1.39.
Here's a short example script that shows the problem:
--------------------------------------------------------
use DBI;
my $dbh =
DBI->connect("dbi:ODBC:DSN=<DSN>;UID=<UID>;PWD=<PWD>;Database=<DB>;Trusted_Connection=No;APP=$0;MARS_Connection=No;");
my $obj = new Object();
my $sql = q(
SELECT ? AS result
);
my $sth = $dbh->prepare($sql);
$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) }
--------------------------------------------------------
With DBD-ODBC-1.23, the output is 'Object'. With DBD-ODBC-1.24 and
later, the output is something like '▒▒8▒6'.
Here's the relevant trace outputs for comparison:
1.39:
-> bind_param for DBD::ODBC::st (DBI::st=HASH(0x1fb2668)~0x1fb2608 1
Object=HASH(0x1fb22c0)) thr#1e85010
+dbd_bind_ph(2020348, name=1, value=Object=HASH(0x1fb22c0),
attribs=, sql_type=0(unknown), is_inout=0, maxlen=0
-dbd_bind_ph=rebind_param
+rebind_param 1 Object=HASH(0x1fb22c0) (size
svCUR=33237088/SvLEN=0/max=0) svtype 4, value type:1 sql type:0
+get_param_type(2020348,1)
Parameter 1
SQLDescribeParam failed, sv=0 bytes, defaulting to 12
07009 [Easysoft][SQL Server Driver 10.0][SQL Server]Invalid descriptor index
bind 1 Object=HASH(0x1fb22c0) value_len=6 maxlen=-1 null=0)
bind 1 value_type:1 VARCHAR cs=80 dd=0 bl=6
-rebind_param
<- bind_param= 1 at odbc.pl line 13
1.23:
-> bind_param for DBD::ODBC::st (DBI::st=HASH(0x1d126d8)~0x1d12678 1
Object=HASH(0x1f06e98)) thr#1c79010
+dbd_bind_ph(1e14348, name=1, value='Object', attribs=,
sql_type=0(unknown), is_inout=0, maxlen=0
+get_param_type(1e14348,1)
SQLDescribeParam failed reverting to default SQL bind type -1
07009 [Easysoft][SQL Server Driver 10.0][SQL Server]Invalid descriptor index
-dbd_bind_ph=1
<- bind_param= 1 at odbc.pl line 13
Applying this patch to dbdimp.c restores the 1.23 behavior:
--- DBD-ODBC-1.39-release/dbdimp.c 2012-08-07 13:44:09.000087000 -0400
+++ DBD-ODBC-1.39-modified/dbdimp.c 2012-08-07 13:42:56.000315000 -0400
@@ -6490,7 +6490,7 @@
if (!strcmp(imp_dbh->odbc_dbms_name, "Microsoft SQL Server")) {
if (DBIc_TRACE(imp_dbh, CONNECTION_TRACING, 0, 0))
TRACE0(imp_dbh, "Deferring Binding\n");
- imp_dbh->odbc_defer_binding = 0;
+ imp_dbh->odbc_defer_binding = 1;
}
/* check to see if SQLMoreResults is supported */
rc = SQLGetFunctions(imp_dbh->hdbc, SQL_API_SQLMORERESULTS,
&supported);
Trying to set $dbh->{odbc_defer_binding} = 1 from Perl has no effect.
Perl version: 5.10.1 (64-bit)