Предотвратите ошибку «Команды вне синхронизации» из хранимой процедуры MySQL, вызываемой через AJAX - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть хранимая процедура MySQL, которая обновляет данные в наборе таблиц (в основном для одной записи в основной таблице и связанных записей в наборе дочерних таблиц).Он вызывается через AJAX через функцию PHP.(То есть вызов AJAX относится к странице PHP, которая в конечном итоге вызывает этот SP.) Он работал нормально, но теперь я пытаюсь заставить его сделать еще одну вещь и запускаю команду «Синхронизировано; вы можете«Запустите эту команду сейчас».

Изменение заключается в сохранении еще одного элемента в основной таблице, но для этого может потребоваться добавить элемент в дочернюю таблицу (называемую ActionTopic).Страница позволяет пользователю выбрать из выпадающего списка или ввести новое значение.Я добавил два параметра в SP: один - это выбранный ПК в раскрывающемся списке, другой - новое введенное значение. В SP я добавил приведенный ниже код.Он проверяет, было ли введено новое значение. Если это так, он вызывает другой SP, который проверяет, находится ли введенное значение в таблице, и, если нет, добавляет его.(Я пытался с помощью кода проверить и добавить запись в строке, а не в отдельном SP, и у меня та же проблема.)

if cNewTopic <> '' then
    -- First, make sure the new topic isn't already there
    call aoctest.AddActionTopic(cNewTopic);
    -- SELECT @iTopicID := iID FROM ActionTopic WHERE UPPER(Description) = UPPER(cNewTopic);
    SET @iTopicID = LAST_INSERT_ID();
else
    SET @iTopicID = Topic;
end if;

Страница работает, если пользователь делает выбор из выпадающего списка,Проблема возникает только тогда, когда пользователь вводит новое значение.Даже когда я получаю ошибку, все остальное работает как положено.Новое значение добавляется в дочернюю таблицу, а родительская таблица и другие дочерние элементы обновляются, как ожидается.

Интересно, что если я вызываю SP в MySQL Workbench с теми же параметрами (после того, как нового значения нет в новой таблице), он запускается без ошибок.Единственное, что я заметил, это то, что я получаю две строки в разделе «Вывод» MySQL Workbench, а не одну.Оба показывают звонок в ИП.Первая показывает «1 возвращенная строка (и)» и период времени, а вторая показывает «0 возвращенная строка (и)» и «- / 0,000 сек».Вызов SP в MySQL Workbench, где новое значение уже находится в таблице, также показывает две строки в разделе «Вывод», но вторая показывает «1 возвращенная строка (и)».

Не уверен, есть ли какое-либодругого кода нужен здесь.Если вы считаете, что мне нужно показать больше, пожалуйста, спросите.

ОБНОВЛЕНИЕ: Основываясь на комментарии Пита Дишмана, я более внимательно посмотрел, где происходит ошибка.Это не оригинальный вызов SP, выдающий ошибку.Это следующий вызов MySQL, который все еще находится внутри вызова Ajax.

Код, обрабатывающий результат, уже имеет следующий код:

//not sure why next line should be needed.
mysqli_next_result($conn);

Я попробовал оба, просто удвоив вызов mysqli_next_result (то есть, два подряд) и помещая это в петлю по линиям, предложенным Питом.С двумя звонками я все равно получаю ту же ошибку.С циклом я жду 30 секунд и затем получаю ошибку 500: Внутренняя ошибка сервера.

ОБНОВЛЕНИЕ 2: Я попытался с циклом для mysqli_more_results () (аналогично тому, что в ответе Пита Дишмана) и выводил счетчиквнутри петли.Код привел мое интернет-соединение к ползанию, и мне, наконец, пришлось прервать его, но было множество итераций цикла.Просто попробовал следующее:

        mysqli_free_result($result);
        $result = mysqli_store_result($conn);
        mysqli_free_result($result);

        if (mysqli_more_results($conn)) {
            $result = mysqli_store_result($conn);
            mysqli_free_result($result);
        }
        $allresult = getsubmissions($conn);

Обнаружил заметную задержку, прежде чем она не удалась.

Даже если вы не можете сказать мне, что не так, я был бы признателен за идеи, как это отладить.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Я решил свою проблему, переработав код, который обрабатывает результат следующим образом:

        if (mysqli_more_results($conn)) {
            mysqli_free_result($result);
            mysqli_next_result($conn);
            $result = mysqli_store_result($conn);
            mysqli_free_result($result);

            if (mysqli_more_results($conn)) {
                mysqli_next_result($conn);
                $result = mysqli_store_result($conn);
                if (!is_null($result) and gettype($result)!== 'boolean') {
                    mysqli_free_result($result);
                }
            }
        }
        $allresult = getsubmissions($conn);
0 голосов
/ 11 февраля 2019

Это может быть связано с тем, что хранимая процедура возвращает несколько наборов результатов (две строки в рабочей среде).Когда вы запрашиваете у php, вам нужно получить оба набора результатов, прежде чем вы сможете отправить другой запрос, в противном случае вы получите ошибку «command of sync».

Документация подразумевает, что это только в случае использования mysqli_multi_query но у нас это есть в нашем коде при использовании mysqli_real_query.

Наш код запроса выглядит следующим образом:

mysqli_real_query($conn, $sql);

$resultSet = mysqli_store_result($conn);

while (!is_null($row = mysqli_fetch_array($resultSet, MYSQLI_BOTH)))
{
    $results[] = $row;
}

mysqli_free_result($resultSet);

// Check for any more results
while (mysqli_more_results($conn))
{
    if (mysqli_next_result($conn))
    {
        $result = mysqli_store_result($conn);
        if ($result !== FALSE)
        {
            mysqli_free_result($result);
        }
    }
}

return $results;

Код, очевидно, будет другим, если вы используете PDO, но тот же принцип может применяться (см. http://php.net/manual/en/pdostatement.nextrowset.php)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...