Otrzymuję błędy „String data, right truncation” z PHP za pomocą ODBC i łączenie się z instancją Microsoft SQL Server 2008R2

Używam PHP 5.3.3 na pudełku CentOS 6.2, łącząc się z instancją Microsoft SQL Server 2008R2. Połączenie działa i mogę pobrać dane, o ile moje zapytania nie zawierają żadnych parametrów. Gdy dodaję parametry, pojawia się błąd „Dane ciągu, prawe obcięcie”.

Oto przykładowy kod:

<?php

$dbh = new PDO("odbc:myDSN", 'myUsername', 'myPassword');

$testCase = 1;
switch ($testCase) {
case 1:
  //  This case fails with this error:
  //    Error 22001: [Microsoft][ODBC Driver 11 for SQL Server]String data, right truncation (SQLExecute[0] at /builddir/build/BUILD/php-5.3.3/ext/pdo_odbc/odbc_stmt.c:254)
  $query = "select * from [myDatabase].[sys].[objects] WHERE (([name]=?))";
  $stmt = $dbh->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++;
}

Zauważ, że oba przypadki testowe w powyższym kodzie powinny zrobić to samo. Przypadek testowy 1 wykorzystuje parametry (jak powinien być cały kod), a przypadek testowy 2 wyraźnie umieszcza odpowiednią wartość w zapytaniu SQL. Działa test case 2. Przypadek testowy 1 nie. Próbowałem zastąpić 'bindParam ()' za pomocą 'bindValue ()', ale nie ma to żadnego skutku. Próbowałem również użyć nazwanych parametrów (np.:name) zamiast parametrów pozycyjnych, ale to również nie ma wpływu. Próbowałem dodać jawny argument długości do bindParam () (używającstrlen($param1) jako wartość), ale daje to naprawdę dziwny komunikat o błędzie (Incorrect syntax near 'OUTPUT') i mogę tylko założyć, że robię to źle. Parametry całkowite działają poprawnie. Tylko parametry ciągu zawodzą.

Jakieś pomysły, dlaczego to nie działa?

Oczywiście jest możliwe, że w sterowniku ODBC występuje błąd lub że nie jest on zgodny z moją wersją PHP lub z wieloma podobnymi problemami, ale mam nadzieję, że po prostu używam API nieprawidłowo.

Edytować:

Według sugestii Andy Iancu zagłębiłem się w SQL Server Profiler. W przypadku śledzenia przypadek 1 daje dwie prawie identyczne rekordy, jedną klasySQL:BatchStartingi jeden z klasySQL:BatchCompleted, oba zawierające tekst:

set fmtonly on select [name] from [myDatabase].[sys].[objects] where 1=2 set fmtonly off

Przypadek 2 daje dwa rekordy, obie klasy „RPC: Completed”. Pierwszy zawiera tekst:

declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,NULL,N'select * from [myDatabase].[sys].[objects] WHERE (([name]=''testtable1''))'
select @p1

a drugi zawiera tekst:

exec sp_unprepare 1

Aktualizacja:

W desperackim ruchu, mając nadzieję, że pojawi się jakiś problem z upuszczeniem nowej wersji unixODBC do istniejącej wersji PHP, przekompilowałem PHP ze źródła. To okazuje się trudniejsze niż mogłoby się wydawać w CentOS. Niestety nie miało to żadnego skutku. Te same błędy dookoła.

questionAnswers(2)

yourAnswerToTheQuestion