【发布时间】:2018-06-04 17:15:56
【问题描述】:
尝试了我能想到的所有方法,但我已将范围缩小到“?”占位符。
我试过替换“?”带有随机文本的占位符,一切正常(当然除了它不断覆盖同一行)。
我得到的错误:
您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在 '?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 附近使用的正确语法 重复密钥更新 第 2 行的产品
这是我的代码(我会提供更多,但除了这个错误之外,它一切正常,如果我删除“?”占位符,那么除了值不是动态的之外,所有的都可以正常工作,但请询问您是否怀疑问题在别处):
// Create MySQL connection to ds_signifyd_api
$mysqli = mysqli_connect( $db_server_name, $db_username, $db_password, $db_name );
// Check connection
if ($mysqli->connect_error) {
exit( $mysqliFailedBody );
}
$mainProdQueryStmt = "INSERT INTO products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
//... more variables here...
$tags = mysqli_real_escape_string($mysqli, $tags);
if (!mysqli_query($mysqli, $mainProdQueryStmt)) {
printf("Errormessage: %s\n", mysqli_error($mysqli));
}
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
$mainProdQuery->execute();
// $mainProdQuery->close();
}
更新
实施了此处提到的修复:
1.停止使用mysqli_real_escape_string
2. 在循环外绑定变量
3. 仅使用面向对象的方法,而不是像 mysqli_query($mysqli, $mainProdQueryStmt) VS $mysqli->prepare($mainProdQueryStmt) 那样混合它们,因为它应该是 - 这解决了“?”错误报告占位符语法错误
现在一切正常,没有错误。
更新代码:
$mainProdQueryStmt = "INSERT INTO dss_products (`product_id`, `title`, `body_html`, `vendor`, `product_type`, `created_at`, `handle`, `updated_at`, `published_at`, `template_suffix`, `published_scope`, `tags`)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
product_id = VALUES(product_id),
title = VALUES(title),
body_html = VALUES(body_html),
vendor = VALUES(vendor),
product_type = VALUES(product_type),
created_at = VALUES(created_at),
handle = VALUES(handle),
updated_at = VALUES(updated_at),
published_at = VALUES(published_at),
template_suffix = VALUES(template_suffix),
published_scope = VALUES(published_scope),
tags = VALUES(tags)";
$mainProdQuery = $mysqli->prepare($mainProdQueryStmt);
if ($mainProdQuery === FALSE) {
die($mysqli->error);
}
$product_id = $product_title = $body_html = $vendor = $product_type = $created_at = $handle = $updated_at = $published_at = $template_suffix = $published_scope = $tags = "";
$mainProdQuery->bind_param("isssssssssss", $product_id, $product_title, $body_html, $vendor, $product_type, $created_at,
$handle, $updated_at, $published_at, $template_suffix, $published_scope, $tags);
if ($mainProdQuery) {
foreach ($dss_product_db_array as $product) {
$product_id = $product['id'];
$product_title = $product['title'];
$body_html = $product['body_html'];
$vendor = $product['vendor'];
$product_type = $product['product_type'];
$created_at = $product['created_at'];
$handle = $product['handle'];
$updated_at = $product['updated_at'];
$published_at = $product['published_at'];
$template_suffix = $product['template_suffix'];
$published_scope = $product['published_scope'];
$tags = $product['tags'];
if (!$mysqli->prepare($mainProdQueryStmt)) {
printf("Errormessage: %s\n", $mysqli->error);
}
$mainProdQuery->execute();
}
}
【问题讨论】:
-
您的代码没有意义。您稍后会使用准备好的语句,您正在使用
mysqli_real_escape_string()并且有一些未知变量。好的,你在下面有答案,处理这些。我现在就带路。 -
为了使用占位符,您需要使用
->prepare()而不是mysqli_query()。$mysqli->prepare($mainProdQueryStmt)不是mysqli_query($mysqli, $mainProdQueryStmt) -
如果它覆盖了同一行,那么你需要看看你的
KEY -
注意:
mysqli的面向对象接口明显不那么冗长,使代码更易于阅读和审核,并且不容易与过时的mysql_query接口混淆。在您对程序风格投入过多之前,值得转换一下。示例:$db = new mysqli(…)和$db->prepare("…")程序接口是 PHP 4 时代引入的mysqliAPI 的产物,不应在新代码中使用。