Intereting Posts

Как я могу убедиться, что я поймал все ошибки из MySQLi :: multi_query?

Документы для multi_query говорят:

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

Документы для 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>"; }