3

MSSQLに対してPDOを使用しており、ネストされたクエリを実行する必要があります。それらはすべて準備されたステートメントです。fetch()メソッドを使用しようとすると、内部クエリがすぐに失敗するため、fetchAll()を使用しました。だから、私はプログラム、製品、予算でこのようなものを手に入れます:

$pgm_stmt->execute();
$pgm_res = $pgm_stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($pgm_res as $pgmrow) {
    $prod_stmt->execute(array($pgmrow['ID']));
    $prod_res = $prod_stmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($prod_res as $prodrow) {
        $bdgt_stmt->execute(array($pgmrow['ID'], $prodrow['ID']));
        $bdgt_res = $bdgt_stmt->fetchAll(PDO::FETCH_NUM);
        foreach ($bdgt_res as $bdgtrow) {
            ... work here
        }
    }
}

OK、すべてが最初から機能しますが、2番目のプログラムにループバックすると、製品の結果セットが何らかの理由で破損します。fetchAll()の直後に$ prod_res変数をダンプすると、値はメモリの他の部分、他の配列のビットなどからランダムに割り当てられます。もちろん、$ prodrow ['ID']値が未定義であるため、失敗します。その結果セット全体が壊れています。

誰かが私がこれをトラブルシューティングするのを手伝ってもらえますか?私は困惑しています。

ありがとう。

4

1 に答える 1

1

バグではなく機能です。https ://bugs.php.net/bug.php?id=65945 を参照してください。

これは、MSSQL (TDS)、DBLIB、および FreeTDS の動作です。接続ルールごとに 1 つのステートメント。別のステートメントを開始すると、前のステートメントはキャンセルされます。

以前のバージョンでは、結果セット全体がメモリにバッファリングされ、結果セットが大きい場合に OOM エラーが発生していました。

以前の動作は、必要に応じて fetchAll() とループを使用して複製できます。もう 1 つの回避策は、ステートメントごとに 1 つずつ、2 つの接続オブジェクトを開くことです。

于 2016-10-05T16:25:26.743 に答える