2013-01-10 52 views
5

我已经问了一些关于在PHP的多重查询中捕获错误的问题,但是没人回答。现在我已经搜索了一些,并更多地了解了这个问题。如果发生错误,让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。我怎样才能做到这一点?

非常感谢。

+0

我没有看到任何地方$测试的定义或任何它调用的方法如果我们不知道你的代码在做什么 – Kyle

+0

$ test = new mysqli(“localhost”,“root”,“”,“testdatabase”); – Shiuyin

+0

如果SQL错误是可能的,预期的结果,那么你做错了事。 '做类似于SQL客户端(或终端)的东西你为什么一次真的需要执行这么多的查询? –

回答

0

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

如果您想了解更多有关该错误有两种选择:

丑陋的人做$Query = implode(";\n\n",$Query);,然后分析该行提供错误信息和匹配。

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

0

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

  • 使用三张报表
  • 因为你的三个疑问是非常相似的,你应该使用一个事先准备好的声明,并执行了三份次与不同的参数绑定。这比三个单独的语句提供了更好的性能,并且使SQL注入变得不可能。
  • 你可以设计一客一换,所有这样的查询或UNION做任何事情:

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

如果你现在觉得“这是什么人说什么?这不会是原子了,“那么你应该使用一个交易...

+0

“这不会再是原子了。” - multi_query也不是原子的。 – johannes

+0

@johannes:是的,但你可以认为 –

+0

这就是为什么我说清楚:-) – johannes

相关问题