2016-07-06 119 views
0

所以除了DB連接器,我沒有包括什麼可能會導致我得到這個錯誤?Mysqli多查詢

您的SQL語法錯誤;檢查對應於你的MySQL服務器版本的手冊正確的語法使用近「UPDATE EVENTDATA SET設備ID =‘631403956MB21’WHERE設備ID =「4631403956MB」第1" 行

這是我的PHP mysqli的多查詢。

$sql = "UPDATE Device  SET deviceID = \"631403956MB21\" WHERE 
    deviceID = \"4631403956MB2\" "; 

    $sql .= "UPDATE EventData SET deviceID = \"631403956MB21\" WHERE 
    deviceID = \"4631403956MB2\" "; 

    $sql .= "UPDATE NotifyQueue SET deviceID = \"631403956MB21\" WHERE 
    deviceID = \"4631403956MB2\" "; 

    $sql .= "UPDATE RuleTrigger SET deviceID = \"631403956MB21\" WHERE 
    deviceID = \"4631403956MB2\" "; 

    $sql .= "UPDATE RuleList SET deviceID = \"631403956MB21\" WHERE 
    deviceID = \"4631403956MB2\" "; 

    $result = mysqli_multi_query($db, $sql); 

    if ($result) { 
     echo 'true'; 
    } else { 
     echo 'false';   
     echo mysqli_error($db); 
    } 

    mysqli_close($db); 

謝謝, 邁克

+0

爲了使您的代碼更易讀的使用單引號像'$ SQL雙引號的字符串=「更新設備SET設備ID =‘631403956MB21’WHERE 設備ID =‘4631403956MB2’」;' – RiggsFolly

+0

你們是不是要更改主這個陳述的關鍵? – RiggsFolly

+0

你正在運行mysqli_multi_query錯誤的方式。通常在循環中更好地運行單獨的查詢 - 它會減少對您的問題。 –

回答

-1

你不應該在同一個查詢多個UPDATE條款。你試圖使用mysqli_multi_query,但你需要你的查詢用分號隔開:

首先創建一個數組:

$queries = [ 
    "UPDATE Device...", 
    "UPDATE EventData...", 
    "UPDATE NotifyQueue...", 
]; 

從那裏,你有兩個選擇。首先是循環並執行查詢一次

foreach($queries as $sql): 
    $result = mysqli_query($db, $sql); 
    ... 
endforeach; 

這不是一個好主意,但因爲它需要很多旅行到數據庫。更好的選擇是什麼,你實際上是試圖做:執行多查詢語句

$multi_query = implode('; ',$queries); 
mysqli_multi_query($db, $multi_query); 
... 

重要提示

multi_query不使用準備好的語句,所以如果你不小心,你將容易受到SQL注入攻擊。採用這種方法時,一定要將您的字符串轉義並將所有數字值作爲數字(例如:$var = (int)$var),然後將其包含在查詢中。

順便說一句,我注意到你在多個表上做了deviceID的相同更改。這可能表明你的架構設計不佳。如果您有InnoDB表,則可以使用主鍵和外鍵來指示EventData,NotifyQueue ...中的deviceID表是鏈接到Device表中的主鍵的外鍵。然後,如果您將更改設置爲更新級聯,則只需更改Device表中的ID,並且DB將負責在其他地方更改它。這是一個quick intro to the concept。插入時

+0

這不是一個答案。當您要發表評論時請使用評論 – RiggsFolly

+0

謝謝;你在重寫中遇到了我。如果修改後的答案滿足您,請刪除downvote。 – BeetleJuice

1

禁用自動提交/更新多個查詢和使用循環:

$mysqli = dbConnect(); // Connect with database 
$mysqli->autocommit(FALSE); // Set autocommit off 

// You can prepare and bind outside the foreach loop, so you don't 
// have to write and bind each query individually. 

$sql = "UPDATE RuleList SET deviceID = ? WHERE deviceID = ?"; 
$stmt = $mysqli->prepare($sql); 
$stmt->bind_param('ii', $deviceID1, $deviceID2); 

foreach($ids as $id): 
    $deviceId1 = $id; 
    $stmt->execute(); 
endforeach; 

$stmt->close(); 
$mysqli->commit(); // Commit all queries 
$mysqli->close(); 

以上是一個例子

+0

感謝您最近的貢獻。看來你知道你在說什麼 - 這裏很少見的事情。請訪問更多。 –

+0

@YourCommonSense把那些花時間去幫助你的人放下來真的不好。 @rhazen你的解決方案是有趣的感謝分享。我運行了一些使用你的方法和我的方法更新3000行的時間測試,結果是非常不同的。通過創建一個準備好的語句並像循環一樣在循環中調用'execute',該過程在我的設置上持續約550毫秒。通過轉義變量,像我在解決方案中一樣構建一個查詢數組並使用一個'multi_query'調用,相同的數據庫更新只需要大約7毫秒。快100倍。 – BeetleJuice

+0

@BeetleJuice你確定你使用了所有這些代碼,包括一個事務嗎? –

0

正確的查詢:

UPDATE Device  SET deviceID = '631403956MB21' WHERE deviceID = '4631403956MB2'; 
UPDATE EventData SET deviceID = '631403956MB21' WHERE deviceID = '4631403956MB2'; 
... 

所以,最後,你做不分配「;」在每個查詢結束時。您只分配一個「;」在PHP代碼的末尾。

$sql = "UPDATE Device  SET deviceID = \"631403956MB21\" WHERE 
deviceID = \"4631403956MB2\" "; 
$sql .= "UPDATE EventData SET deviceID = \"631403956MB21\" WHERE 
deviceID = \"4631403956MB2\" "; 
... 

↓↓↓

$sql = "UPDATE Device  SET deviceID = '631403956MB21' WHERE 
deviceID = '4631403956MB2'; "; 
$sql .= "UPDATE EventData SET deviceID = '631403956MB21' WHERE 
deviceID = '4631403956MB2'; "; 
... 

請嘗試,並希望它能幫助。