Hi there,

yesterday I've got the following problem:

> example:
----------------------- SNIP SNIP ----------------
use DBI;

$connection = DBI->connect("DBI:ODBC:mydb", q(user), q(passw));
if(($DBI::err != 0) || !$connection) {
  die "not connected!\n";
}

$csr = $connection->prepare("select 1 from table_that_does_not_exist");
if(($DBI::err != 0) || !$csr) {
  die "got no cursor!\n$DBI::err\n$DBI::errstr\n";

}

if(!defined($csr->{NUM_OF_PARAMS}) || !$csr->{NUM_OF_PARAMS}) {
  print "executing!\n";
  $csr->execute();
  print "executed!\n";
} else { print "not executed!\n";
}

$connection->disconnect();
------------- SNIP SNIP ------------

> When connecting to a ms sql database on a win32 plattform
> using the odbc driver version 3.70.08.21, prepare fails as expected.
>
> when connecting to the same database on a win32 plattform
> using the odbc driver version 2000.81.9031.14, prepare does not fail.
> Failure occurs at the subsequent $csr->{NUM_OF_PARAMS} expression.

the problem seems to be in the SQL_SOPT_SS_DEFER_PREPARE Option.
In the newer driver, this option is set by default. It causes the sql engine
not to
parse the statement immediately, i.e. while the DBD-prepare function.

When a malformed statement is prepared, there is no error code sent back, so
it
crashes either in $csr->execute or in the $csr->{NUM_OF_PARAMS}.

The solution is to set this option to "off".
The older driver version does not support this option, so when DBI_TRACE >=
2,
you'll find an appropriate message.

finally, in the following lines, you will find a patch for the dbdimp.c
file:

----------------------- SNIP SNIP ---------------
> #include "ODBCSS.h"
13a15,17
> #define SQL_SOPT_SS_DEFER_PREPARE (SQL_SOPT_SS_BASE+7)
> #define SQL_DP_OFF 0
> #define SQL_DP_ON  1
1336a1341,1347
>     }
>
>     rc = SQLSetStmtAttr ( imp_sth->hstmt, SQL_SOPT_SS_DEFER_PREPARE,
SQL_DP_OFF, 0);
>
>     if (DBIc_DEBUGIV(imp_sth) >= 2 && !SQL_ok(rc))
>     {
>         PerlIO_printf(DBIc_LOGPIO(imp_dbh), "    SQLSetStmtAttr
SQL_SOPT_SS_DEFER_PREPARE returned %d\n\n",rc);
--------------------- SNIP SNIP --------------------

Regards,
Martin


Reply via email to