Код, который должен делать запросы в цикле, выполняет только один, и выдает предупреждение `mysqli_num_rows() expects parameter 1 to be mysqli_result

Есть 2 таблицы.
В первой таблице нужно обновить количество работ для выполнения для каждого отдельного задания, а из второй удалить запись о выполнении работы при условии, что работа не была выполнена в срок.
Вроде бы скрипт работает, но не так как надо, и выдает предупреждение mysqli_num_rows() expects parameter 1 to be mysqli_result.
Требуется чтобы обновлялись сразу все строки в таблице, где выполняются условия.
То есть в одной таблице нужно подсчитать количество невыполненных в срок работ для каждого задания, и добавить это количество уже во второй таблице по одному запросу.
Сейчас обновляется только одна строка, и чтобы получить нужный результат, приходится несколько раз перезагружать страницу.

<?php
    $now = time();
    $db->Query("SELECT * FROM db_task_progress WHERE `check_string` = '' AND `date_del` < '$now'");
    while ($db -> NumRows() > 0) {
        $taskex = $db -> FetchArray(); 
        $idex = $taskex['id'];
        $task_idex = $taskex['task_id'];
        $db -> Query("SELECT (SELECT COUNT(*) FROM db_task_progress WHERE check_string = '' AND date_del < '$now' AND task_id = '$task_idex') all_add");
        $addex = $db -> FetchArray();
        $all_add = $addex['all_add'];
        $db -> Query("UPDATE `db_task` SET `number` = `number` + '$all_add' WHERE `id` = '$task_idex'");
        $db -> Query("DELETE FROM `db_task_progress` WHERE `check_string` = '' AND `date_del` < '$now' AND task_id = '$task_idex'");
    }
?>

Ответы (1 шт):

Автор решения: Ипатьев

Проблема заключается в самопальной библиотеке, использующейся для выполнения запросов. И это очень частая проблема, практически все новички с ней сталкиваются.

Такая библиотека не должна сохранять состояние запросов.

  • Надо или использовать два класса вместо одного, чтобы в итоге был один основной объект, содержащий соединение с БД, который создает отдельные объекты второго класса для каждого запроса.
  • иди сделать так, чтобы все методы, выполняющие запросы, были атомарными, то есть чтобы сразу возвращали результат, и не пытались сохранить его состояние.

В противном случае мы имеем то что имеем - последующий запрос (на удаление) переписывает сохраненный результат предыдущего (селекта), и при попытке обратиться к нему закономерно возвращает ошибку.

Причем это еще хорошо, что мы получаем ошибку. Поскольку конструкция while ($db -> NumRows() > 0) { является бессмысленной сама по себе, и если бы ошибки не было, то мы бы получили бесконечный цикл.

В качестве решения проблемы я настоятельно рекомендую отказаться на время от написания и использования самопальных библиотек, и научиться использовать родную mysqli. Которая, к тому же, в настоящее время в сто раз удобнее любых самопалов.

→ Ссылка