2013-01-10 50 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

相關問題