php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48295 ODBC and bound parameters
Submitted: 2009-05-15 13:18 UTC Modified: 2020-09-28 13:37 UTC
Votes:5
Avg. Score:5.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:0 (0.0%)
From: christian dot ehlscheid at gmx dot de Assigned: cmb (profile)
Status: Duplicate Package: PDO ODBC
PHP Version: 5.2.9 OS: Windows XP
Private report: No CVE-ID: None
 [2009-05-15 13:18 UTC] christian dot ehlscheid at gmx dot de
Description:
------------
Hi,

this is a reopening of Bug # 36561 - http://bugs.php.net/36561

After this comment:
"This appears to be a bug with prepared statements in the underlying
microsoft client driver implementation..."
the bug was marked as bogus.

I would call it a limitation, a well documented one (http://msdn.microsoft.com/en-us/library/ms130945.aspx), and I think it is a PDO ODBC bug.

I had a look at the source code of the PDO ODBC driver and this issue can easily be fixed, and it should be in my opinion.

Here's the code that should be altered:
function "odbc_stmt_param_hook" in the file "odbc_stmt.c"

"rc = SQLDescribeParam(S->stmt, param->paramno+1, 
&sqltype, &precision, &scale, &nullable);

if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
/* MS Access, for instance, doesn't support SQLDescribeParam,
 * so we need to guess */
		sqltype = PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB ? SQL_LONGVARBINARY : SQL_LONGVARCHAR;

..."

The code tries to get the datatype of the bound parameter with the call to the ODBC API function SQLDescribeParam, which fails under MSSQL/MS Access and other databases.

Then it sets the sqltype variable (which holds the ODBC datatype under which the parameter is later bound) to SQL_LONGVARCHAR or SQL_LONGVARBINARY .. 

the comment in the code tells it all .. "so we need to guess" .. 

the solution is quite simple -> don't guess. 

The correct ODBC datatype can be deduced from the type of the bound PHP variable, and if the developer specified a concrete type in the bindParam call (e.g. $oStatement->bindParam(':TestID', $iTestID,PDO::PARAM_INT ); ) the whole call to SQLDescribeParam is not neccessary and the PDO type specified should be directly mapped to the equivalent ODBC datatype.

Now the problematic code and the solution is known and I hope someone will fix it.

Christian

Reproduce code:
---------------
MSSQL:
CREATE TABLE zTest_TBL (
	TestID int NULL 
) 
INSERT INTO zTest_TBL (TestID) Values (1)

PHP:
<?
$iTestID=1;
$oConnection = new PDO($sDSN, $GLOBALS["sDatabase_Username"],
$GLOBALS["sDatabase_Password"]);
$oStatement = $oConnection->prepare('SELECT TestID FROM zTest_TBL WHERE
TestID IN (SELECT TestID FROM zTest_TBL WHERE TestID = :TestID)');
//$oStatement = $oConnection->prepare('SELECT TestID FROM zTest_TBL
WHERE TestID = :TestID AND TestID  IN (SELECT TestID FROM zTest_TBL
)');
$oStatement->bindParam(':TestID', $iTestID,PDO::PARAM_INT );
$oStatement->execute() or print_r($oStatement->errorInfo());
foreach($oStatement as $aRow) {
  print_r($aRow);
}
?>



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-01-01 12:50 UTC] felipe@php.net
-Package: PDO related +Package: PDO ODBC
 [2020-09-28 13:37 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Assigned To: +Assigned To: cmb
 [2020-09-28 13:37 UTC] cmb@php.net
Duplicate of bug #44643.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 07:01:29 2024 UTC