我正在使用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的问题:

should fix insertMulti() if onDuplicate() is set

10-08 14:00