如果发生错误,请继续PHP多查询

时间:2013-01-10 12:11:35

标签: php error-handling multi-query

我已经问过一些关于在PHP中使用多个查询捕获错误的问题,但是没有人回答。现在我用谷歌搜索了一下,更多地了解了这个问题。

我得到了这个代码:

// Some starting variables
$test = new mysqli("localhost","root","","testdatabase");
$Query = array();
$Query[] = "SELECT 'wos' FROM items WHERE itemID = 3";
$Query[] = "SELECT 'wos' FROM items WHERE itemID";
$Query[] = "SELECT 'wos' FROM items WHERE itemID = 5";
$Query = implode(";",$Query);
$Errors = array();

// Execute multi query

if ($test->multi_query($Query)) {
  do {
    // fetch results
    $Result = $test->store_result();
    print_r($Result);
    if($test->errno === 0) {
          echo $Result->num_rows . "<br>";
    }
    else {
        $Errors[] = $test->error;
    }
    $Result->close();

    if (!$test->more_results()) {
      break;
    }
    if (!$test->next_result()) {
      $Errors[] = $test->error;
      break;
    }
  } while (true);
}

正如您所看到的,我有许多X个后续查询,并想要执行所有查询。因此,如果查询2失败,我想继续多查询以运行以下查询。我怎么能这样做?

此外,如果发生错误,我想在$Errors中保存此错误。但是目前它并没有按预期工作,因为我只能保存错误消息而不能保存相应的查询。如果没有失败的查询,只有错误消息才真正有用。所以我希望有类似的内容:"Query 3 failed ('SELECT ...'): 'ERROR MESSAGE'"

这怎么可能?我能够使用$test->error获取循环中的当前错误,但我没有$test->currentsubsequentquery之类的内容。我怎么能这样做?

非常感谢。

2 个答案:

答案 0 :(得分:0)

这里的问题可以称为MySQL协议中的限制。当使用多查询时(从MySQL的角度来看:将多语句选项设置为On然后发送查询),服务器将拆分它并一个接一个地执行它们。答案将在不参考原点的情况下发送。客户端(在本例中为PHP / mysqli)可以找出与错误相关的实际语句的唯一方法是解析完全查询字符串并尝试进行一些映射。但是在许多情况下这不起作用 - 一些语句,尤其是CALL,可以返回多个无法映射到语句的结果集。

如果您想了解有关错误的更多信息,有两种选择:

丑陋的人正在进行$Query = implode(";\n\n",$Query);,然后解析所提供行的错误消息并与之匹配。

或者根本不使用multi_query。 multi_query用于处理返回多个结果集的存储过程调用。在上述情况下使用multi_query只会节省很小的延迟,因为服务器可以直接处理下一个查询而无需等待下一个查询命令,但即使这样也可以通过使用mysqlnd的异步查询操作来实现。

答案 1 :(得分:-1)

嗯,单个语句中的多个查询通常不是一个好主意。好的SQL客户端(例如PDO)根本不允许多个查询,因为这种方式使SQL注入变得更加困难。 我想劝阻你的想法,并提出以下解决方案之一:

  • 使用三个单一陈述
  • 由于您的三个查询非常相似,因此您应该使用预准备语句并使用不同的参数绑定执行三次。这提供了比三个单个语句更好的性能,并使SQL注入成为不可能。
  • 你可以像这样设计一对一的查询,或者用UNION做任何事情:

    "SELECT 'wos' FROM items WHERE itemID IN ('3', '5')"
    

如果你现在想“这个人在说什么?这不再是原子的。”那么你应该使用交易......