## Множественные запросы

MySQL поддерживает наличие нескольких SQL-запросов в тексте одного запроса, но требует особого обращения. Пересылка на сервер нескольких выражений в одном запроса уменьшает количество клиент-серверных взаимодействий, но требует специальной обработки.

Множественные запросы, или мультизапросы, должны запускаться функцией mysqli::multi_query(). Отдельные SQL-предложения в мультизапросе отделяются точкой с запятой. После выполнения мультизапроса все результирующие наборы, которые он вернул, необходимо извлечь.

MySQL-сервер поддерживает наличие в одном мультизапросе подзапросов, как возвращающих результирующий набор, так и не возвращающих.

Пример #1 Множественные запросы

    <?php

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli("example.com", "user", "password", "database");

    $mysqli->query("DROP TABLE IF EXISTS test");
    $mysqli->query("CREATE TABLE test(id INT)");

    $sql = "SELECT COUNT(*) AS _num FROM test;
            INSERT INTO test(id) VALUES (1);
            SELECT COUNT(*) AS _num FROM test; ";

    $mysqli->multi_query($sql);

    do {
        if ($result = $mysqli->store_result()) {
            var_dump($result->fetch_all(MYSQLI_ASSOC));
            $result->free();
        }
    } while ($mysqli->next_result());

Результат выполнения приведённого примера:

    array(1) {
      [0]=>
      array(1) {
        ["_num"]=>
        string(1) "0"
      }
    }
    array(1) {
      [0]=>
      array(1) {
        ["_num"]=>
        string(1) "1"
      }
    }

Рассмотрение аспектов безопасности

Функции API mysqli::query() и mysqli::real_query() во время работы не устанавливают на сервере специальный флаг, необходимый для выполнения мультизапросов. Отдельная API-функция для мультизапросов позволяет снизить вероятность случайных SQL-инъекций. Злоумышленник может попытаться добавить в конец запроса выражения, вроде `; DROP DATABASE mysql` или `; SELECT SLEEP(999)`. Если ему это удастся, но не будет использоваться функция mysqli::multi_query(), сервер не выполнит внедрённое и опасное SQL-выражение.

Пример #2 SQL-инъекция

    <?php
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli("example.com", "user", "password", "database");
    $result = $mysqli->query("SELECT 1; DROP TABLE mysql.user");
    ?>

Результат выполнения приведённого примера:

    PHP Fatal error:  Uncaught mysqli_sql_exception: You have an error in your SQL syntax;
    check the manual that corresponds to your MySQL server version for the right syntax to
    use near 'DROP TABLE mysql.user' at line 1

Подготавливаемые запросы

Использование множества выражений в подготавливаемом запросе не поддерживается.

Смотрите также

- mysqli::query()
- mysqli::multi_query()
- mysqli::next_result()
- mysqli::more_results()

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open