Mysqli_multi_query не работает надежно с запросами условного комментария mysql
У меня возникла проблема с запросами условного комментария mysql, где сообщаются ошибки без синтаксической ошибки. Он работает в том случае, если по крайней мере один из запросов выполняется с условным.
Я использую php 5.6.24 и mysql 5.5.52-cll
Пример 1 (Успех):
<?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));
?>
Значение
supports_full_text равно 0, как ожидалось.
Пример 2 (Отказ):
<?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));
Полученные ошибки:
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
)
)
Пример 3 (Отказ, но выглядит как успех (см. ниже сообщение):
<?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));
Значение теста равно 0. Как и ожидалось.
Является ли это ошибкой в php или чем-то, что я делаю неправильно?
EDIT:
ПРИМЕЧАНИЕ. Я обнаружил, что когда запрос не выполняется, STOPS обрабатывает остальную часть файла. Таким образом, пример 3 все еще имеет ошибки во 2-м и 3-м запросах; Я просто не поймал все ошибки. Выполняется запрос 40000; но все, что НЕ запускается для текущей версии mysql, терпит неудачу как синтаксическая ошибка.
Ответы
Ответ 1
У вас есть недоразумение здесь. Ваша версия mysql 5.5.52
. Это означает, что результаты, которые вы получаете, верны.
Когда вы скажете /*!40000 ... */
в своем запросе, вы говорите, что этот запрос должен выполняться только в версиях mysql выше 4.0.0. Аналогично, /*!50604 ... */
означает, что версия mysql должна быть выше, чем 5.6.04
, чтобы этот запрос выполнялся. Помните, что эти цифры относятся к версии mysql. Не для версии php.
В первом тесте ваш первый запрос выполняется отлично, так как ваша версия mysql больше 4.0.0. Но второй запрос пропущен, так как ваша версия mysql ниже 5.6.04. Это то, что происходит и в двух других тестах.
Но я не могу объяснить, почему вы получаете синтаксические ошибки, например,
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
во втором тесте. Может быть, запрос, который вы здесь задаете, - это не фактический запрос, который вы выполнили. Вы можете это проверить? Поскольку я также делал все эти тесты (у меня есть mysql 5.5
, а также php 5.6
), я не обнаружил никаких ошибок. Я только видел, что запросы с более высокими требованиями к версии не выполняются.
Для дополнительного чтения см. в этой статье. Надеюсь, мой ответ вам помог.
Обновление
Посмотрев на другие ответы, похоже, вы столкнулись с редкой ошибкой. Попробуйте обновить версию mysql. Если проблема все еще сохраняется, это может быть ошибка с API mysql.
Ответ 2
Да, похоже, что это ошибка в multi_query()
. Кажется, эта функция не любит неуместную точку с запятой.
$mysqli->multi_query(";SELECT 1;");
даст вам ту же синтаксическую ошибку. Также как и запрос SELECT 1;;SELECT 2;
.
Что делает любой условный комментарий, оцененный как false
, выдает дополнительную точку с запятой, что приводит к синтаксической ошибке.
Update.
Похоже, что это не mysqli, а mysql API очень разборчивы по точкам с запятой: эта проблема может быть воспроизведена и в PDO. Похоже, я напишу ошибку на трекер mysql.
Ответ 3
Multi-statement - опасный инструмент; избегайте этого.
В любом случае, вам это действительно нужно? Вы можете сделать несколько строк в одном выражении:
REPLACE INTO `phppos_app_config` (`key`, `value`)
VALUES
('test', '0'),
('test', '1')
BTW, REPLACE
- старая команда; INSERT ... ON DUPLICATE KEY UPDATE ...
в основном заменил его. Подумайте об этом.
Или, может быть, вы можете просто использовать INSERT IGNORE ...
.
Пожалуйста, объясните свою цель использования /*!50604 ... */
. Он в основном существует, чтобы дать некоторую форму обратной совместимости в инструментах; он редко используется в производственной среде.