0

これは PHP & MySQL Novice to Ninja, 5th Editionbyの一部ですKevin Yank

通常、SELECT クエリを実行するときは、while ループまたは foreach ループの条件を使用して、結果の各行を一度に 1 つずつ取得します。

while ($row = $result->fetch()) foreach ($result as $row)

この方法でクエリの結果を処理すると、PHP は実際には、ループが要求したときにデータベースから各行を取得し、次の行に移動するときにそれを破棄します。これにより、PHP は大量のメモリを使用して結果のすべての行を一度に保持する必要がなくなります。

ほとんどの場合、私たち開発者は、PHP がこの巧妙な近道を取っていることを知る必要はありません。しかし、前のクエリのすべての結果を処理する前に、別の SQL クエリを MySQL サーバーに送信したい場合があります。

注意を怠ると、このコードでまさにこれが起きようとしています。SELECT クエリを実行して、特定の作者に属するすべてのジョークのリストを要求し、そのリストを調べていると、それぞれに対して DELETE クエリを実行したいと思います。問題は、MySQL が知る限り、まだ SELECT クエリの結果を送信するのに忙しいことです。ただ中断して、DELETE の実行を開始するように要求することはできません。これを行うと、DELETE がエラーで失敗します。

そこで fetchAll メソッドの出番です。準備済みステートメント ($s) でこのメソッドを呼び出すことにより、クエリの結果セット全体を取得し、それらを PHP 配列 ($result) に格納するように PHP に要求します。

PDOStatement result sets私の質問は、PHP コードで1 つ以上を使用しているときに MYSQL ステートメントを実行できるのはなぜですか? deleteそれらで参照されているすべての行を使用することもできますresult sets

<?php
    include_once $_SERVER["DOCUMENT_ROOT"] . '/DBconnection.inc.php';

        $pds1 = $dbi->query("SELECT name FROM tbl1");
        $row = $pds1->fetch();
        var_dump($row['name']);

        $pds2 =  $dbi->query("SELECT user FROM tbl2");
        $row = $pds2->fetch();
        var_dump($row['user']);

        $row = $pds1->fetch();
        var_dump($row['name']);

        $row = $pds2->fetch();
        var_dump($row['user']);

        $pds3= $dbi->prepare("DELETE FROM tbl1;");
        $pds3->execute();

        $row = $pds1->fetch();
        var_dump($row['name']);

        $row = $pds2->fetch();
        var_dump($row['user']);



?>
4

1 に答える 1

1

これは、PDOの動作が、使用しているデータベースとPDOドライバーの実装に依存する領域です。selectステートメントの結果をフェッチしている間に新しいクエリを実行できる場合と、できない場合があります。

一般に、PDO接続を使用する最も安全で互換性のある方法は次のとおりです。

  1. SELECTステートメントを実行します
  2. 必要なすべての行をフェッチします
  3. カーソルを閉じます(例:with $pds1->closeCursor()
  4. 次のクエリを実行する
于 2012-11-14T17:30:21.770 に答える