4

タイトルがばかげているように聞こえることは知っていますが、何時間も調査を行った結果、PDO は最終的にバグがあり、明確な解決策がないことがわかりました...私は 1 つを開くことに専念しています。また、私のコードに欠陥があることも受け入れます。

PHP 5.2/Ubuntu を使用すると、このコードは機能します (準備済みステートメントを使用しない/インジェクション可能):

$sql ="SELECT COUNT(*) FROM property p
INNER JOIN property_attribute pa ON p.property_id = pa.property_id
INNER JOIN property_area pc ON p.property_id = pc.property_id
WHERE pa.attribute_value_id
    IN (
        SELECT av.attribute_value_id
        FROM attribute_value av
        INNER JOIN attribute a ON av.attribute_id = a.attribute_id
        WHERE a.name LIKE '$attributes'
        AND av.value LIKE '$values'
    ) 
ORDER BY p.price ASC";
$params = array();
$rHowManyPages = Listings::HowManyPages($sql, $params);

ただし、PDO のすばらしい準備済みステートメントを使用すると、次のようになります。

$sql ='SELECT COUNT(*) FROM property p
INNER JOIN property_attribute pa ON p.property_id = pa.property_id
INNER JOIN property_area pc ON p.property_id = pc.property_id
WHERE pa.attribute_value_id
    IN (
        SELECT av.attribute_value_id
        FROM attribute_value av
        INNER JOIN attribute a ON av.attribute_id = a.attribute_id
        WHERE a.name LIKE :attributes
        AND av.value LIKE :values
    ) 
ORDER BY p.price ASC';
$params = array(':attributes' => $attributes, ':values' => $values);
$rHowManyPages = Listings::HowManyPages($sql, $params);

それはちょっと動作します。スパルタニックの狂気の部分は次のとおりです。渡される同じデータの 5 回の更新に 1 回、PDO は次のエラーを返します。

TEXT: SQLSTATE[HY093]: Invalid parameter number

ランダムです!方法と理由?

4

1 に答える 1

5

名前付き引数に指定された値の 1 つに疑問符が含まれている可能性はありますか? 私はそれで問題に遭遇しましたが、それはずっと前のことです。(私は確かに彼らが今までにそれを修正していると思います。)

私の限られた経験では、「名前付き引数」に対する PDO のサポートはやや大ざっぱです。

たとえば、ステートメント内の複数の場所で同じ名前付き引数を使用することはできません。各名前付き引数のプレースホルダー名は一意である必要があり、一度しか使用できません。そして、それは名前付き引数の大きな利点の 1 つを水から吹き飛ばします。

値の疑問符文字で遭遇した問題と、名前付き引数を複数回参照できない (これは確認していません) のは、PDO の「名前付き引数」サポートがボルトオンの後付けであるためだと思います。位置引数のサポートへ。基本的に、「名前付き引数」が位置引数に変換されているようです。

また、名前付き引数にアンダースコア文字が含まれていると、おかしなことにも遭遇しました。

私の回避策は、(ACCCKKK!) 名前付き引数の代わりに位置引数を使用することでした。

(私は位置引数を使用するのが嫌いですが、それは私にとってはうまくいきました。)

(あなたが示したコードには、観察された動作を説明するものは何もありません。明らかに、あなたが示していない他のコードがあります。)

$paramsまた、配列に 2 つの要素のみが含まれていることを確認することもできます。配列に「余分な」一致しない要素がある場合、同じエラーメッセージが表示されました。それからまた、私のコードでは、PDO で混乱させるのではなく、スカラーのみを使用してそれぞれを個別にバインドすることに戻りました。(私にとっては問題ではありませんでした。これは、私が Perl DBI でよく知っているパターンです。問題をデバッグするのではなく、問題を回避しました。)


注:位置引数とは、名前の代わりに疑問符を使用することを意味します。

 $sql = " ...
  WHERE a.name LIKE ?
    AND av.value LIKE ?
 ... ";

$sth->bindParam(1, $attributes);
$sth->bindParam(2, $values);
于 2012-07-27T22:19:36.147 に答える