我制作了一个向数据库添加订单的脚本。插入时(我可以通过每次用户访问页面时查询数据库50次来完成许多字段,因此必须进入一个查询。
我制作了一个脚本,动态添加链接到数组中给定数据量的选定数量的记录。
但是每当我尝试执行查询时,它都会给我一个错误,即我的语法不正确。
我的代码:
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}
答案 0 :(得分: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
}