最好检查的是已经导入到MySQL表中的产品:
1)按每个产品ID的每次查询
foreach ($products_to_import_from_xml as $product) {
$is_exist = $modx->query("SELECT id FROM modx_ms2_products WHERE crm_id={$product['id']} LIMIT 1")->fetch(PDO::FETCH_COLUMN);
if ($is_exist) continue;
actually_import_new_product_because_it_not_exist_yet($product);
}
或
2)使用“。。。WHERE`id`IN(array,of,all,importing,IDs)”?
$product_ids_to_import = [];
foreach ($products_to_import_from_xml as $product) {
$product_ids_to_import[] = $product['id'];
}
$existing_products = $modx->query('SELECT crm_id FROM modx_ms2_products WHERE crm_id IN ('.implode(',', $product_ids_to_import).')')->fetchAll(PDO::FETCH_COLUMN);
foreach ($products_to_import_from_xml as $product) {
$is_exist = in_array($product['id'], $existing_products);
if ($is_exist) continue;
actually_import_new_product_because_it_not_exist_yet($product);
}
一般来说,我推荐使用MySQL中的insert.。。on duplicate key
语法。
为此,您需要在products表上有一个惟一(或主键)约束。 如果它还没有,请创建它:
create unique index idx_product_id on products(product_id);
然后在应用程序代码的foreach循环中,可以执行以下操作:
insert into products(product_id, ...) -- enumerate all target columns here
values(:product_id, ...) -- enumerate all input parameters here
on duplicate key update set product_id = values(product_id);
当MySQL遇到已经存在的product_id
时,它会跳过insert
并转到on duplicate key
子句,在该子句中执行虚拟更新(实际上并没有重写该值,因为它与表中已经存在的值相同)。
请注意,如果要导入大量数据,则可以考虑其他替代方案,而不是在应用程序端循环并每行执行单独的insert
。 对于高性能的插入,MySQL推荐使用load data infile
语法,根据文档化,它的运行速度是单个插入的20倍。 这将需要将XML数据转换为CSV格式,但这可能是值得的。