Я получаю ошибки «Строковые данные, правильное усечение» из PHP с использованием ODBC и подключением к экземпляру Microsoft SQL Server 2008R2
Я использую PHP 5.3.3 на коробке CentOS 6.2, подключаясь к экземпляру Microsoft SQL Server 2008R2. Соединение работает, и я могу получать данные, если мои запросы не содержат параметров. Когда я добавляю параметры, я получаю ошибку "Строковые данные, правое усечение ".
Вот'Пример кода:
prepare($query);
$param1 = 'testtable1';
$stmt->bindParam(1, $param1, PDO::PARAM_STR); // Note: '1' is correct; it should not be '0'
break;
case 2:
// This case works properly
$query = "select * from [myDatabase].[sys].[objects] WHERE (([name]='testtable1'))";
$stmt = $dbh->prepare($query);
break;
}
$execResult = $stmt->execute();
if ($execResult) {
print "Success!\n";
} else {
$errorInfo = $stmt->errorInfo();
print "Error " . $stmt->errorCode() . ": " . $errorInfo[2] . "\n";
}
$rowCount = 0;
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "Row " . $rowCount . ":\n";
foreach ($row as $key => $value) {
printf(" %-20s %s\n", $key, $value);
}
$rowCount++;
}
Обратите внимание, что оба тестовых примера в приведенном выше коде должны выполнять одно и то же. В тестовом примере 1 используются параметры (как должен делать весь код), а в тестовом примере 2 явно указывается соответствующее значение в запросе SQL. Тестовый пример 2 работает. Контрольный пример 1 не делает. Я попытался заменить 'bindParam ()» с 'bindValue ()», но это не имеет никакого эффекта. Я'Мы также пытались использовать именованные параметры (например,:name
) вместо позиционных параметров, но это также не имеет никакого эффекта. Я'мы пытались добавить явный аргумент длины в bindParam () (используяstrlen($param1)
в качестве значения), но это дает действительно странное сообщение об ошибке (Incorrect syntax near 'OUTPUT'
), и я могу только предположить, что яЯ делаю это неправильно. Целочисленные параметры работают правильно. Сбой только строковых параметров.
Любые идеи, почему это не такт работает?
Конечновозможно, что тамошибка в драйвере ODBC, или что этоне совместимы с моей версией PHP или с другими подобными проблемами, но я надеюсь, чтоЯ просто неправильно использую API.
Редактировать:
Пер Анда ЯнкуС этим предложением я углубился в SQL Server Profiler. При отслеживании случай 1 дает две почти идентичные записи, одну из классаSQL:BatchStarting
и один из классаSQL:BatchCompleted
оба содержат текст:
set fmtonly on select [name] from [myDatabase].[sys].[objects] where 1=2 set fmtonly off
Случай 2 дает две записи, оба класса "RPC: Completed», Первый содержит текст:
declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,NULL,N'select * from [myDatabase].[sys].[objects] WHERE (([name]=''testtable1''))'
select @p1
а второй содержит текст:
exec sp_unprepare 1
Обновить:
В отчаянном шаге, надеясь, что может быть какая-то проблема с переносом новой версии unixODBC в существующую версию PHP, я перекомпилировал PHP из исходного кода. На CentOS это оказывается сложнее, чем вы думаете. К сожалению, это не имело никакого эффекта. Все те же ошибки.