Документы для multi_query
говорят:
Возвращает FALSE, если первый оператор не сработал. Чтобы получить последующие ошибки из других операторов, вы должны сначала вызвать mysqli_next_result ().
- Вставка нескольких строк в базу данных MySQL из таблицы
- mysqli фатальная ошибка: индекс не используется в запросе / подготовленном сообщении
- Предупреждение: mysql_query (): доступ запрещен для пользователя 'admin' @ 'localhost' (с использованием пароля: НЕТ)
- Нестатический метод mysqli :: init () нельзя назвать статическим
- PHP.ini вызывает Предупреждение: mysqli_error () ожидает, что параметр 1 будет mysqli, null указан в / sys / index.php в строке 19
Документы для next_result
говорят:
Возвращает TRUE при успешном завершении или FALSE при сбое.
Наконец, пример, размещенный в документах для multi_query
использует возвращаемое значение next_result
чтобы определить, когда больше нет запросов; например, для остановки цикла:
<?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()); // <-- HERE! } /* close connection */ $mysqli->close(); ?>
Я не знаю количество предоставленных запросов и не знаю ничего о SQL, который я собираюсь выполнить. Поэтому я не могу просто сравнить количество запросов с количеством возвращаемых результатов. Тем не менее, я хочу показать сообщение об ошибке пользователю, если, скажем, третий запрос был сломанным запросом. Но мне кажется, что у меня нет возможности определить, не произошло ли next_result
потому что запросов больше не было, или это связано с тем, что в синтаксисе SQL произошла ошибка.
Как я могу проверить все запросы на ошибки?
Несмотря на пример кода в документах, возможно, лучшим способом было бы что-то вроде этого:
if ($mysqli->multi_query(...)) { do { // fetch results if (!$mysqli->more_results()) { break; } if (!$mysqli->next_result()) { // report error break; } } while (true); }
Невозможно поймать все ошибки, посмотрите пример, который вы используете (который отсюда )
Этот пример содержит только «select» в нем, что не является общим для сценариев с несколькими операторами.
Если вы поместите «вставить», «обновить», «удалить» или, по крайней мере, «установить» – он будет работать по-другому.
«multi_query» – возвращает FALSE, если первый оператор не сработал. ПЕРВОЕ ЗАЯВЛЕНИЕ – это все, что мы можем контролировать. Все последующие утверждения таинственны. Если это не оператор «select», он выдаст ошибку «$ mysqli-> store_result ();» и мы никогда не знали, было ли это успешным или нет.
НО
Если у вас будет ваш SQL-скрипт в «START TRANSACTION; … commit;» обертка, вы можете быть уверены – если что-то не сработает, все провалится. Это хорошо, это помогает нам понять, «все ли не удается».
Для этого просто добавьте в конце скрипта «insert-update» немного «select», если последний оператор возвращает данные – все скрипты успешно завершены.
Используйте SQL как:
START TRANSACTION; set @q=1; select "success" as response from dual; commit;
Функция PHP:
function last_of_multi_query ($mysqli, $query) { mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); //After that all mysql errors will be transferred into PHP exceptions. $mysqli->multi_query($query); do { null; } while($mysqli->next_result()); $result = $mysqli->store_result(); if (!$result){ throw new Exception('multi_query failed'); } return $result; }// end function
Ответ Билла Карвина выглядит не очень красноречивым для меня. Кажется странным писать отдельные условные разрывы, когда цикл while while уже настроен для обработки контрольных точек.
Я не тестировал следующий фрагмент, но вы должны иметь доступ к необходимым результатам и ошибкам:
$queries["CURRENT_USER"]="SELECT CURRENT_USER()"; $queries["CITY_NAME"]="SELECT Name FROM City ORDER BY ID LIMIT 20, 5"; if(mysqli_multi_query($mysqli,implode(';',$queries))){ do{ list($current_table,$current_query)=each($queries); if($current_table!="CURRENT_USER"){ printf("-----------------\n"); } if($result=mysqli_store_result($mysqli)){ if(mysqli_num_rows($result)<1){ echo "<p>Logic Error @ $current_table Query<br>$current_query</p>"; }else{ while($row=mysqli_fetch_row($result)){ printf("%s\n",$row[0]); } } mysqli_free_result($result); } } while(mysqli_more_results($mysqli) && mysqli_next_result($mysqli)); }else{ list($current_table,$current_query)=each($queries); } if($error=mysqli_error($mysqli)){ echo "<p>Syntax Error @ $current_table Query<br>$current_query<br>Error: $error</p>"; }
в$queries["CURRENT_USER"]="SELECT CURRENT_USER()"; $queries["CITY_NAME"]="SELECT Name FROM City ORDER BY ID LIMIT 20, 5"; if(mysqli_multi_query($mysqli,implode(';',$queries))){ do{ list($current_table,$current_query)=each($queries); if($current_table!="CURRENT_USER"){ printf("-----------------\n"); } if($result=mysqli_store_result($mysqli)){ if(mysqli_num_rows($result)<1){ echo "<p>Logic Error @ $current_table Query<br>$current_query</p>"; }else{ while($row=mysqli_fetch_row($result)){ printf("%s\n",$row[0]); } } mysqli_free_result($result); } } while(mysqli_more_results($mysqli) && mysqli_next_result($mysqli)); }else{ list($current_table,$current_query)=each($queries); } if($error=mysqli_error($mysqli)){ echo "<p>Syntax Error @ $current_table Query<br>$current_query<br>Error: $error</p>"; }