web-dev-qa-db-ja.com

PHP / MYSQLで2つのmysqlクエリを1つとして実行するにはどうすればよいですか?

次の2つのクエリがあります。

SELECT SQL_CALC_FOUND_ROWS Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
SELECT FOUND_ROWS();

これらの両方のクエリを1回で実行したいと思います。

$result = mysql_query($query);

しかし、それでは、各テーブルセットを個別に処理する方法を教えてください。実際にASP.NETでは、2つのクエリを次のように処理するデータセットを使用します。

ds.Tables[0];
ds.Tables[1]; .. etc

PHP/MYSQLを使用して同じことができますか?

29
Prashant

更新:mysql_connect()にフラグを渡すことにより、明らかに可能です。 PHPを使用して1つのステートメントで複数のSQLクエリを実行する を参照してください。ただし、現在の読者はmysql_-クラスの関数とPDOを好みます。

PHPで通常のmysql-apiを使用してそれを行うことはできません。 2つのクエリを実行するだけです。 2番目のものは非常に高速であるため、問題にはなりません。これは、マイクロ最適化の典型的な例です。心配しないでください。

レコードについては、mysqliおよび mysqli_multi_query -functionを使用して実行できます。

32
Emil H

他の人が答えたように、mysqli APIはmsyqli_multi_query()関数で複数クエリを実行できます。

価値のあるものとして、PDOはデフォルトで複数クエリをサポートし、複数のクエリの複数の結果セットを反復処理できます。

$stmt = $dbh->prepare("
    select sql_calc_found_rows * from foo limit 1 ; 
    select found_rows()");
$stmt->execute();
do {
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
} while ($stmt->nextRowset());

ただし、マルチクエリは、セキュリティ上の理由から悪いアイデアとかなり広く考えられています。クエリ文字列の作成方法に注意を払わない場合、実際には クラシック「リトルボビーテーブル」XKCD漫画 に示されている正確なタイプのSQLインジェクションの脆弱性を取得できます。単一クエリに制限するAPIを使用する場合、それは起こり得ません。

8
Bill Karwin

あなたはMySQLiを使用する必要があります、以下のコードはうまくいきます

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$query  = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";

/* execute multi query */
if ($mysqli->multi_query($query)) {
    do {
        /* store first result set */
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->free();
        }
        /* print divider */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
    } while ($mysqli->next_result());
}

/* close connection */
$mysqli->close();
?>
3
user2155518

SQL_CALC_FOUND_ROWSを使用することはできません。

FOUND_ROWS()を介して使用可能な行カウントは一時的なものであり、SELECT SQL_CALC_FOUND_ROWSステートメントに続くステートメントを超えて使用できるようには意図されていません。

前の質問で誰かが指摘したように、SQL_CALC_FOUND_ROWSの使用は、カウントを取得するよりも頻繁に遅くなります。

おそらく、これをサブクエリとして行うのが最善でしょう。

SELECT 
 (select count(*) from my_table WHERE Name LIKE '%prashant%') 
as total_rows,
Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
3
tpdi

クエリを2回実行したくない場合は、MySQLi拡張機能を使用する必要があります。

if (mysqli_multi_query($link, $query))
{
    $result1 = mysqli_store_result($link);
    $result2 = null;

    if (mysqli_more_results($link))
    {
        mysqli_next_result($link);
        $result2 = mysqli_store_result($link);
    }

    // do something with both result sets.

    if ($result1)
        mysqli_free_result($result1);

    if ($result2)
        mysqli_free_result($result2);
}
3
Jon Benedicto

このような:

$result1 = mysql_query($query1);
$result2 = mysql_query($query2);

// do something with the 2 result sets...

if ($result1)
    mysql_free_result($result1);

if ($result2)
    mysql_free_result($result2);
1
Jon Benedicto

PHPサイトで 複数のクエリは許可されていません (編集:これはmysql拡張機能にのみ当てはまります。mysqliとPDOは複数のクエリを許可します)。したがって、PHPでは実行できませんが、別のmysql_query呼び出しでそのクエリを実行できないのはなぜですか(Jonの例のように)?同じ接続を使用します。また、 mysql_num_rows も役立ちます。

1
Michael Pryor

はい、MySQLi拡張機能を使用せずに可能です

単にCLIENT_MULTI_STATEMENTS in mysql_connectの5番目の引数。

詳細については、以下のコメントを参照してください Husniの投稿

0
Pacerier