2014-09-06 116 views
0

我正在製作一個向數據庫添加訂單的腳本。插入時(很多領域我不能簡單地通過查詢數據庫50次,每次用戶訪問該頁面,因此它必須進入一個單一的查詢。執行數組數組時出現PHP PDO錯誤

我做了一個腳本,動態地添加選定的數量記錄鏈接到陣列中的給定的數據量

但每當我試圖執行查詢它給了我一個錯誤,我的語法不正確

我的代碼:。

private function addOrderDetails($products, $orderID) { 
    # Base of the query (will be the end result) 
    $query = 'INSERT INTO `Database`.`orderDetails` (
     `amount`, 
     `price`, 
     `tax`, 
     `product_id`, 
     `order_id` 
    ) VALUES (:?, :?, :?, :?, :?)'; 

    # Added to the query if there are more than 1 products 
    $queryExtension = ', (:?, :?, :?, :?, :?)'; 
    $queryPayload = array(); 

    # Loop through all products and add them to the query payload 
    foreach ($products as $counter => $productArray) { 
     # Add all values individually 
     foreach ($productArray as $value) { 
      array_push($queryPayload, $value); 
     } 

     # Add the orderID at the end and extend the query (if the key is more than 0) 
     array_push($queryPayload, $orderID); 
     if ($counter > 0) $query .= $queryExtension; 
    } 

    # Execute the array 
    $query = $this->DB->prepare($query); 
    $query->execute($queryPayload);  # Error on this exact line, if I put an exit; here it throws no error. 
} 

我與數據數組:

array(
    array(
     'amount' => 50, 
     'price'  => 10, 
     'tax'  => 2, 
     'productID' => 5 
    ), 
    array(
     'amount' => 27, 
     'price'  => 19, 
     'tax'  => 6, 
     'productID' => 15 
    ), 
    array(
     'amount' => 492, 
     'price'  => 2300, 
     'tax'  => 4.5, 
     'productID' => 50 
    ) 
); 

我的錯誤:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 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 ':'50', :'10', :'2', :'5', :'42'), (:'27', :'19', :'6', :'15', :'42'), (:'492', :' at line 7' in (webroot) 
Stack trace: 
#0 (webroot): PDOStatement->execute(Array) 
#1 (webroot): Database->addOrderDetails(Array, '42') 
#2 (webroot): Database->addOrder(1, '1', Array) 
#3 {main} 
+3

鬆散的冒號。非命名佔位符是'?',而不是':?'。您還可以使用'$ array [] ='add this';'將元素添加到數組中。它比使用'array_push'更短,並且保存了一個函數調用 – 2014-09-06 16:39:54

+0

@EliasVanOotegem哦,哇,那簡直是愚蠢的我。謝謝! – Paradoxis 2014-09-06 16:42:51

回答

0

就像我在我的評論說,命名佔位符開始用冒號。您似乎沒有使用指定的佔位符,因此常規問號將會執行。 IE將:?替換爲?。這就是說,你似乎錯過了使用準備語句的最佳部分:你可以重複使用不同值的準備好的查詢。你加入,並添加到查詢字符串的時候根本沒有必要:

$query = 'INSERT INTO `Database`.`orderDetails` (
     `amount`, 
     `price`, 
     `tax`, 
     `product_id`, 
     `order_id` 
    ) VALUES (?, ?, ?, ?, ?)'; 
$stmt = $pdo->prepare($query); 
$pdo->beginTransaction();//best use transactions here, though 
foreach ($products as $counter => $productArray) 
{ 
    $bind = array_values($productArray);//though strictly speaking, this isn't required 
    $stmt->execute($bind);//add this array 
    $stmt->closeCursor(); 
} 
$pdo->commit(); 

已準備語句是預編譯的,預先優化的查詢時,只需要輸入(即值插入)以便執行。如果可以提前編譯和優化查詢,爲什麼不可能多次使用相同的資源?從上面的代碼可以看出:你可以用這個重新使用聲明,你所要做的(不是嚴格要求,但最好你這樣做),就是通知PDO(和DB)每次完成聲明的運行。 PDOStatement::closeCursor爲您做到這一點。

因爲你試圖在一個查詢中插入數據,所以我建議使用一個事務。這樣,如果其中一個查詢失敗,可能會拋出異常,並且您可以撤消所有您現在運行的查詢:

try 
{ 
    $pdo->beginTransaction(); 
    //same code as above 
    $pdo->commit();//save changes 
} 
catch (PDOException $e) 
{//something went wrong 
    $pdo->rollBack();//undo changes 
}