2017-01-06 13 views
11

Mam problem z mysql warunkowe komentarze kwerendy, w których zgłaszane są błędy bez błędu składni. Działa w przypadku, gdy co najmniej jedno z zapytań faktycznie jest wykonywane z warunkiem warunkowym.mysqli_multi_query nie działa niezawodnie z mysql warunkowym komentarzem zapytań

ja pomocą php 5.6.24 i mysql 5.05.52-CLL

Przykład 1 (sukces):

<?php 
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2"); 

$test1 = " 
/*!40000 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('supports_full_text', '0') */; 
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('supports_full_text', '1') */;"; 

mysqli_multi_query($conn,$test1); 
print_r(mysqli_error_list($conn)); 
?> 

wartość supports_full_text jest 0, jak oczekiwano.

Przykład 2 (niepowodzenie):

<?php 
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2"); 

$test2 = " 
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */; 
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1') */;"; 

mysqli_multi_query($conn,$test2); 
print_r(mysqli_error_list($conn)); 

błędów odbieranych:

Array 
(
    [0] => Array 
     (
      [errno] => 1064 
      [sqlstate] => 42000 
      [error] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; 
    /*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1' at line 1 
     ) 

) 

Przykład 3 (usterka, ale wydaje się, jak sukces (patrz poniżej komunikat)

<?php 
$conn = mysqli_connect("127.0.0.1", "aaatex_phppos", "phppos", "aaatex_phppos2"); 

$test3 = " 
/*!40000 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */; 
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '0') */; 
/*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1') */;"; 

mysqli_multi_query($conn,$test3); 
print_r(mysqli_error_list($conn)); 

testu wartość 0 zgodnie z oczekiwaniami.

Czy jest to błąd w php lub coś, co robię źle?

EDIT:

UWAGA: Okazało się, że gdy zapytanie nie zatrzymuje przetwarzanie resztę pliku. Tak więc przykład 3 nadal zawiera błędy w drugim i trzecim zapytaniu; Po prostu nie złapałem wszystkich błędów. Zapytanie 40000 działa; ale wszystko, co NIE działa dla aktualnej wersji mysql, zawodzi jako błąd składni.

+0

Właśnie testowany przykład nr 3. pracował bez żadnego problemu na MySQL 5.7.16 i PHP 7.0.8. – ICE

+0

@ICE Wyjaśniłem, dlaczego możesz uruchomić go bez problemu w mojej odpowiedzi. Komentarz warunkowy '/ *! 50604 * /' oznacza, że ​​zapytanie powinno zostać wykonane tylko wtedy, gdy wersja mysql jest wyższa niż '5.6.04'. Masz wyższą wersję, więc możesz ją uruchomić. –

+0

@ImeshaSudasingha Przeczytałem twoją odpowiedź i głosowałem w górę. Skomentowałem tutaj, ponieważ widziałem, że otrzymał błąd dla zapytania. – ICE

Odpowiedz

8

Masz tu nieporozumienie. Twoja wersja mysql to 5.5.52. Oznacza to, że wyniki, które otrzymujesz, są poprawne.

Kiedy mówisz /*!40000 ... */ w zapytaniu, to mówią, że to zapytanie powinno się wykonywać wyłącznie w mysql wersji wyższej niż 4.0.0. Podobnie, /*!50604 ... */ oznacza, że ​​wersja mysql powinna być wyższa niż 5.6.04, aby wykonać to zapytanie. Pamiętaj, że te liczby dotyczą mysql version. Nie dla wersji php.

W pierwszym teście twoje pierwsze zapytanie zostanie wykonane poprawnie, ponieważ twoja wersja mysql jest większa niż 4.0.0. Ale drugie zapytanie zostanie pominięte, ponieważ twoja wersja mysql jest niższa niż 5.6.04. To samo dzieje się w dwóch pozostałych testach.

Ale jestem w stanie wyjaśnić, dlaczego są coraz błędy składniowe jak,

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; 
    /*!50604 REPLACE INTO `phppos_app_config` (`key`, `value`) VALUES ('test', '1' at line 1 

w 2. próbie. Może być to zapytanie, które tu umieszczasz, nie jest faktycznym zapytaniem, które wykonałeś. Czy możesz to sprawdzić? Podobnie jak te wszystkie testy (mam mysql 5.5 oraz php 5.6), nie natknąłem się na żaden błąd. Widziałem tylko, że zapytania o wyższych wymaganiach wersji nie są wykonywane.

Dodatkowe informacje można znaleźć na stronie this article. Mam nadzieję, że moja odpowiedź ci pomogła.

Aktualizacja

Patrząc na innych odpowiedzi, jak również, wydaje się, że stoją rzadki bug. Spróbuj zaktualizować swoją wersję mysql. Jeśli problem nadal występuje, może to być błąd w mysql API.

+0

Problem polega na tym, że przestaje on przetwarzać wszystkie zapytania po trafieniu zapytania, które nie ma zastosowania do jego wersji z błędem składni. Powinien po prostu uruchomić i nic nie zmieniać i przejść do następnego oświadczenia –

+0

Jak już wspomniałem w mojej odpowiedzi (Również "ICE" wspomniał to samo w komentarzach), nie otrzymywałem żadnych błędów składniowych. Sprawdzę aktualizację, jeśli jest jakakolwiek różnica. –

+0

@ChrisMuench Myślę, że to błąd. Jeśli możesz, zaktualizuj swój MySQL. – ICE

4

Tak, wygląda na to, że jest to błąd w multi_query(). Wydaje się, że ta funkcja nie lubi źle umieszczonych średników.

$mysqli->multi_query(";SELECT 1;"); 

spowoduje wyświetlenie tego samego błędu składni. Jak również zapytanie SELECT 1;;SELECT 2;.

Który powoduje, że każdy komentarz warunkowy oceniony na false tworzy dodatkowy średnik, co powoduje błąd składni.

Aktualizacja. Okazuje się, że nie jest to mysqli, ale mysql API jest bardzo wrażliwy na średniki: ten problem można również odtworzyć w CHNP. Wygląda na to, że zagram błąd na mysql trackerze.

+0

Czy możesz przesłać zgłoszony tutaj raport o błędzie? –

4

Wielostronicowe to niebezpieczne narzędzie; Unikaj tego.

W każdym razie, czy naprawdę tego potrzebujesz? Można zrobić wiele wierszy w jednym stwierdzeniem:

REPLACE INTO `phppos_app_config` (`key`, `value`) 
    VALUES 
     ('test', '0'), 
     ('test', '1') 

BTW, REPLACE jest stary poleceń; INSERT ... ON DUPLICATE KEY UPDATE ... w większości go zastąpił. Zastanów się, że zamiast tego.

A może możesz użyć po prostu INSERT IGNORE ....

Proszę wyjaśnić cel korzystania z usługi /*!50604 ... */. W większości istnieje, aby zapewnić pewną formę wstecznej kompatybilności narzędzi; rzadko jest przydatny w środowisku produkcyjnym.

+0

Celem jest, ponieważ chcę wykonywać kod tylko wtedy, gdy mają pełne możliwości tekstu w innodb (5.6.4 lub nowszym). –

Powiązane problemy