mysqli_multi_query работает с ошибками

Рейтинг: 0Ответов: 1Опубликовано: 20.04.2015

Выполняю мультизапрос:

INSERT INTO categories (title) VALUES ('dgdfg');
SET @categoryID := LAST_INSERT_ID();
INSERT INTO positions (set_fields, title) VALUES ('10', 'dfgdsfg');
SET @positionID := LAST_INSERT_ID();
INSERT INTO category_position (id_category, id_position) VALUES (@categoryID,  @positionID);
INSERT INTO products (id_position, article, title, price, existence) VALUES 
(@positionID, 'dsfgs', 'gsdgfdsg', '123', 'cxvhxch'),
(@positionID, 'sdfg', 'dsgfdsfgs', '2342', 'fghdfh');
SELECT  @categoryID;

Из этого всего мне нужно получить только ответ последней строчки: SELECT @categoryID;

Делаю это при помощи вот такого некрасивого кода:

if (mysqli_multi_query($DB, $query)) {
        do {
            if ($result = mysqli_store_result($DB)) { /* получаем первый результирующий набор */
                if(!mysqli_more_results($DB)){
                    while ($row = mysqli_fetch_row($result)) {
                            $return = $row[0];
                    }
                }

                mysqli_free_result($result);
            }
        } while (mysqli_next_result($DB));
    }

И получаю следующую ошибку:

<b>Strict Standards</b>:  mysqli_next_result() [<a href='function.mysqli-next-result'>function.mysqli-next-result</a>]: There is no next result set. Please, call mysqli_more_results()/mysqli::more_results() to check whether to call this function/method in <b>E:\OpenServer\domains\shop-cms\manager\handlers\shop\save-category.php</b> on line <b>68</b><br />

Но я не понимаю почему, и как исправить?

P.s. У меня была идея чтобы LAST_INSERT_ID() возвращала сразу первую строку INSERT INTO categories (title) VALUES ('dgdfg');, тогда бы не пришлось перебирать все запросы, а достаточно было бы первого, но я не знаю как это возможно реализовать в SQL.

Ответы

▲ 2

проще всего этот код исправить таким образом

$queries = array(
    "INSERT INTO categories (title) VALUES ('dgdfg')",
    "SET @categoryID := LAST_INSERT_ID()",
    "INSERT INTO positions (set_fields, title) VALUES ('10', 'dfgdsfg')",
    "SET @positionID := LAST_INSERT_ID()",
    "INSERT INTO category_position (id_category, id_position) VALUES (@categoryID,  @positionID)",
    "INSERT INTO products (id_position, article, title, price, existence) VALUES 
    (@positionID, 'dsfgs', 'gsdgfdsg', '123', 'cxvhxch'),
    (@positionID, 'sdfg', 'dsgfdsfgs', '2342', 'fghdfh')",
    "SELECT  @categoryID",
);
foreach($queries as $q)
{
    $res = $DB->query($q);
}
echo $res->fetch_row()[0];

Ну или реализовать первоначальную идею, получив сначала insert_id, а потом выполнив остальные запросы.

$DB->query("INSERT INTO categories (title) VALUES ('dgdfg')");
$id = $DB->insert_id;

И далее выполнить все запросы по порядку.

В общем - не выпендриваться с multi-query на пустом месте, без малейшей на то причины.

Лично меня в этом сомнительном коде куда больше беспокоит добавление данных в запрос напрямую, а не через подготовленные выражения. Я понимаю что в mysqli их использование - та ещё морока, но именно поэтому и надо было либо писать хелпер самому, либо сразу учить PDO. Сейчас же, в нынешнем виде, этот код не представляет никакой ценности и не должен использоваться. Из-за того что данные попадают в запрос напрямую.