mysqli_multi_query对mysql条件注释查询不起作用

时间:2017-01-06 19:36:27

标签: php mysql mysqli

我遇到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中的错误还是我做错了什么?

修改

注意:我发现当查询失败时,它会STOPS处理文件的其余部分。因此,示例3在第2和第3个查询中仍然存在错误;我只是没有发现所有错误。 40000查询有效;但是任何不为当前mysql版本运行的东西都会因语法错误而失败。

3 个答案:

答案 0 :(得分:8)

你在这里有误会。你的mysql版本是5.5.52。这意味着您获得的结果是正确的。

当您在查询中说/*!40000 ... */时,您说这个查询只能在高于 4.0.0 mysql 版本中执行。同样,/*!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),我没有遇到任何错误。我只看到没有执行更高版本要求的查询。

有关其他阅读,请参阅this article。希望我的回答对你有所帮助。

<强>更新

通过查看其他答案,您似乎面临着一个罕见的错误。尝试更新您的mysql版本。如果问题仍然存在,则可能是mysql API的错误。

答案 1 :(得分:4)

是的,看起来像multi_query()中的错误。看起来这个功能并不像错误的分号。

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

会给你相同的语法错误。以及SELECT 1;;SELECT 2;查询。

使得评估为false的条件注释产生额外的分号会导致语法错误。

<强>更新
它变成了它不是mysqli但是mysql API对分号非常挑剔:这个问题也可以在PDO中重现。看起来我会在mysql跟踪器上提交一个bug。

答案 2 :(得分:4)

多语句是一种危险的工具;避免它。

无论如何,你真的需要吗?您可以在一个语句中执行多行:

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

BTW,REPLACE是一个旧命令; INSERT ... ON DUPLICATE KEY UPDATE ...大多取代了它。请考虑一下。

或者你可以简单地使用INSERT IGNORE ...

请说明您使用/*!50604 ... */的目的。它主要用于在工具中提供某种形式的向后兼容性;它在生产环境中很少有用。