php - PHP MySQL重复条目异常 - 带有OnDuplicate的InsertMulti
问题描述
我正在使用 ThingEngineer/PHP-MySQLi-Database-Class,并且尝试在使用 OnDuplicate 时执行多次插入。如果“sku”不存在,目标是插入新的产品记录。如果“sku”确实存在,则应更新“名称”而不是创建新条目。
MySQL 架构:
CREATE TABLE `products` (
`product_pk` bigint(9) NOT NULL,
`product_id` int(20) UNSIGNED NOT NULL,
`name` varchar(255) NOT NULL,
`sku` varchar(16) NOT NULL,
`category` int(10) DEFAULT NULL,
`last_update` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
ALTER TABLE `products`
ADD PRIMARY KEY (`product_pk`),
ADD UNIQUE KEY `sku` (`sku`);
ALTER TABLE `products`
MODIFY `product_pk` bigint(9) NOT NULL AUTO_INCREMENT;
PHP:
$sDate = date("Y-m-d H:i:s");
$lastid = $db->rawQuery('SELECT MAX( product_id ) AS max FROM products');
(!$lastid || !isset($lastid[0]['max'])) ? $pid = 0 : $pid = $lastid[0]['max']++;
foreach ($data as $item){
if (isset($item['sku']) && !null == $item['sku']){
$prod[$pid]['product_id'] = $pid;
$prod[$pid]['sku'] = $item['sku'];
$prod[$pid]['name'] = substr($item['product-name'],0,255);
$prod[$pid]['last_update'] = $sDate;
$pid++;
}
}
$utfEncodedArray =encodeArray($prod, 'UTF-8');
$db->onDuplicate('name', 'product_pk');
$db->insertMulti('products', $utfEncodedArray);
function encodeArray($array, $type)
{
foreach($array as $key => $value)
{
if (is_array($value)){ $array[$key] = encodeArray($value, $type);}else{ $array[$key] = mb_convert_encoding($value, $type);}
}
return $array;
}
我收到的错误是:
Uncaught mysqli_sql_exception: Duplicate entry 'ABC123' for key 'sku'
下面是 insertMulti 调用中使用的数组 $utfEncodedArray 的示例:
Array(
[1] => Array
(
[product_id] => 1
[sku] => ABC123
[name] => product1
[last_update] => 2018-09-08 18:55:20
)
[2] => Array
(
[product_id] => 2
[sku] => ABC124
[name] => product2
[last_update] => 2018-09-08 18:55:20
)
)
到目前为止我尝试过的步骤:
- 删除“产品”表并再次创建它。多次。
- 尝试在 onDuplicate 调用中使用“sku”而不是“product_pk”。
- 尝试了多种排序规则类型
- 尝试在“sku”和“product_id”上使用唯一键
- 当我尝试使用此方法时,所有条目均已正确插入,但再次运行时,它会生成重复项,而不是更新现有行。不知道这是怎么发生的,因为“sku”和“product_id”都是独一无二的。
$prod 数组当前包含相同的值。因此,每次我运行它时,我都希望在初始插入后每次都会更新“last_updated”列。
这是我使用 onDuplicate 的第一次体验,尽管搜索和阅读文档数小时,我仍然迷失了方向。我试图让 db 类处理来自数组的多个插入,但我不反对在迭代我的产品数组时尝试原始查询。
解决方案
当然,当我发布此内容时,我发现了问题...
找到了一个数据库类的分支,它在使用 onDuplicate 时解决了 insertMulti 的问题:
推荐阅读
- django - Django - 使用中间用户组模型
- javascript - 注销频道监听器
- c++ - 为什么 std::is_assignable 不适用于原始类型?(确认)
- javascript - 角度路线不会更新到孩子的路径
- git - 有没有办法在 git 日志中移动提交?
- python - 在 Windows 上获取 Python3 中 .exe 文件的输出
- sharepoint - 在哪里可以找到有关 /_api/web/features/add SharePoint API 的文档?
- xml - Intellij 自定义 XML 标记格式
- symfony - 获取实体的当前实例并将其传递给 Symfony 中的侦听器
- alloy - 使用 Alloy 作为抽象建模语言?