Microsoft SQL Server 2008R2 のインスタンスに接続して、CentOS 6.2 ボックスで PHP 5.3.3 を使用しています。接続は機能し、クエリにパラメーターが含まれていない限り、データを取得できます。パラメータを追加すると、「文字列データ、右が切り捨てられました」というエラーが表示されます。
コード例を次に示します。
<?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++;
}
上記のコードの両方のテスト ケースは同じことを行う必要があることに注意してください。テスト ケース 1 では (すべてのコードがそうであるように) パラメータを使用し、テスト ケース 2 では関連する値を SQL クエリに明示的に配置します。テスト ケース 2 は機能します。テストケース 1 はそうではありません。「bindParam()」を「bindValue()」に置き換えてみましたが、効果がありません。:name
また、位置パラメータの代わりに名前付きパラメータ (例: ) を使用してみましたが、これも効果がありません。bindParam() に明示的な長さ引数を (strlen($param1)
値として使用して) 追加しようとしましたが、本当に奇妙なエラー メッセージ ( Incorrect syntax near 'OUTPUT'
) が表示され、間違っているとしか思えません。整数パラメータは正しく機能します。文字列パラメーターのみが失敗します。
これが機能しない理由はありますか?
もちろん、ODBC ドライバーにバグがあるか、私のバージョンの PHP と互換性がないか、または同様の問題がいくつもある可能性がありますが、単に API を不適切に使用していることを願っています。
編集:
Anda Iancu の提案に従って、私は SQL Server Profiler を掘り下げました。トレースすると、ケース 1 は 2 つのほぼ同一のレコード (1 つは class SQL:BatchStarting
、もう 1 つは class ) を提供SQL:BatchCompleted
し、両方にテキストが含まれています。
set fmtonly on select [name] from [myDatabase].[sys].[objects] where 1=2 set fmtonly off
ケース 2 は、クラス "RPC:Completed" の 2 つのレコードを提供します。最初のテキストには次のテキストが含まれます。
declare @p1 int
set @p1=1
exec sp_prepexec @p1 output,NULL,N'select * from [myDatabase].[sys].[objects] WHERE (([name]=''testtable1''))'
select @p1
2番目には次のテキストが含まれます。
exec sp_unprepare 1
アップデート:
新しいバージョンの unixODBC を既存のバージョンの PHP にドロップすることで何らかの問題が発生することを期待して、私は必死になって PHP をソースから再コンパイルしました。これは、CentOS では思ったより難しいことがわかりました。残念ながら、これは効果がありませんでした。あちこちで同じエラー。