|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2006-02-28 17:10 UTC] travis at raybold dot com
Description:
------------
Connecting to a MSSQL database through PDO_ODBC, I prepare a statement with a bound parameter inside of a subquery, and get a 42000 Syntax Error when I execute it.
The error indicates that it is trying to compare text. ntext or image data, but the table consists solely of one integer field. Moving the bound parameter outside of the subquery makes it work.
I am using PHP 5.1.2, MSSQL 2000, Windows XP, IIS6.
Configure Line: cscript /nologo configure.js "--enable-snapshot-build" "--with-gd=shared"
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);
}
?>
Expected result:
----------------
Array ( [TestID] => 1 [0] => 1 )
Actual result:
--------------
Array ( [0] => 42000 [1] => 306 [2] => [Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator. (SQLExecute[306] at ext\pdo_odbc\odbc_stmt.c:133) [3] => 42000 )
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Oct 28 16:00:01 2025 UTC |
Try using: $oStatement->bindParam(':TestID', $iTestID); instead of: $oStatement->bindParam(':TestID', $iTestID,PDO::PARAM_INT ); The latter is implicitly binding for output, which might be part of your problem.This bug affects my app, too. I'm using PHP 5.2.3 on Windows XP Pro SP2, under both IIS 5.1 and Apache 2.2, with SQL Server 2005 Express. I don't know if it'll help or not, but here's some more reproduce code. Just fix the PDO DSN string to something valid. <?php $db = new PDO("odbc:dsn=$odbcDsn;uid=$user;pwd=$pass"); $createTable = 'CREATE TABLE ##test ( intCol int, textCol varchar(20) )'; $createTable2 = 'CREATE TABLE ##test2 ( intCol2 int, textCol2 varchar(20) )'; $db->exec($createTable); $db->exec($createTable2); $ins = $db->prepare('INSERT INTO ##test (intCol, textCol) VALUES (:i, :t)'); $ins->execute(array('i'=>1, 't'=>'A String')); $ins2 = $db->prepare('INSERT INTO ##test2 (intCol2, textCol2) VALUES (:i, :t)'); $ins2->execute(array('i'=>1, 't'=>'Another String')); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE textCol2 = :t)'); $sel->execute(array('t'=>'Another String')) or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE intCol2 = :i)'); $sel->execute(array('i'=>1)) or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE textCol2 = :t)'); $sel->bindValue('t', 'Another String'); $sel->execute() or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE intCol2 = :i)'); $sel->bindValue('i', 1); $sel->execute() or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE textCol2 = :t)'); $sel->bindValue('t', 'Another String', PDO::PARAM_STR); $sel->execute() or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE intCol2 = :i)'); $sel->bindValue('i', 1, PDO::PARAM_INT); $sel->execute() or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE textCol2 = :t)'); $t = 'Another String'; $sel->bindParam('t', $t, PDO::PARAM_STR); $sel->execute() or var_dump($sel->errorInfo()); $sel = $db->prepare('SELECT * FROM ##test WHERE intCol = (SELECT intCol2 FROM ##test2 WHERE intCol2 = :i)'); $i = 1; $sel->bindParam('i', $i, PDO::PARAM_INT); $sel->execute() or var_dump($sel->errorInfo()); ?>I was able to reproduce this error using the 2008-01-05 snapshot of PDO_ODBC. Reproduce code: --------------- <?php $db = new PDO('odbc:Driver={SQL Server}; Server=localhost; Uid=test; Pwd=test; Database=test;'); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db->exec('CREATE TABLE #foo (id INT NOT NULL)'); $db->exec('INSERT INTO #foo VALUES(1)'); $stmt = $db->prepare('SELECT id FROM #foo WHERE id IN (SELECT id FROM #foo WHERE id = ?)'); $stmt->bindValue(1, 1, PDO::PARAM_INT); $stmt->execute(); var_dump($stmt->fetch(PDO::FETCH_ASSOC)); ?> Expected result: ---------------- array(1) { ["id"]=> string(1) "1" } Actual result: -------------- PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 306 [Microsoft][ODBC SQL Server Driver][SQL Server]The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator. (SQLExecute[306] at ..\pecl_5_2\pdo_odbc\odbc_stmt.c:133)' A trace using the Profiler tool shows that the bound integer value is incorrectly interpreted as text: CREATE TABLE #foo (id INT NOT NULL) go INSERT INTO #foo VALUES(1) go declare @P1 int set @P1=NULL exec sp_prepare @P1 output, N'@P1 text', N'SELECT id FROM #foo WHERE id IN (SELECT id FROM #foo WHERE id = @P1)', 1 select @P1 go Incorrect: N'@P1 text' It should be: N'@P1 int'