php - 处理有关批量插入重复行的反馈
问题描述
我有一项服务,允许用户一次导入多个项目,除了填写表格,上传 csv 文件,其中每一行代表一个项目 - 使用在我的 mysql 数据库中的唯一字段下设置的 id 的实体(只有一个项目可以存在特定的 ID)。
当用户完成上传和 csv 处理后,我想提供有关他们文件中的哪些项目已存在于数据库中的反馈。我决定使用 INSERT IGNORE,从警告中解析 id(正则表达式)并根据收集的 id 检索项目信息(SELECT)。浏览互联网,我没有找到通用的解决方案,所以我想知道这种方法是否正确,特别是在处理大量行(500+)时。
基本理念:
INSERT IGNORE INTO (id, name, address, phone) VALUES (x,xx,xxx,xxxx), (y,yy,yyy,yyyy), etc;
SHOW WARNINGS;
$warning_example = [0=>['Message'=>'Duplicate entry on '123456'...'], 1=>['Message'=>'Duplicate entry on '234567'...']];
$duplicates_count = 0;
foreach($warning_example as $duplicated_item) {
preg_match('/regex_to_extract_id/', $duplicated_item['Message'], $result);
$id[$duplicates_count] = $result;
$duplicates_count++;
}
$duplicates_string = implode(',',$id);
SELECT name FROM items WHERE id IN ($duplicates_string);
此外,由于消息结构每次都相同,因此该任务最简单和最有效的正则表达式是什么。
Duplicate entry '12345678' for key 'id'
Duplicate entry '23456789' for key 'id'
etc.
解决方案
与preg_match
:
preg_match(
"/Duplicate entry '(\d+)' for key 'id'/",
$duplicated_item['Message'],
$result
);
$id[$duplicates_count] = $result[1];
(\d+)
\d
表示应捕获的数字序列 ( )(括在括号内)。
但是,如果您可以控制数据的导入方式,还有更好的方法可以继续。首先,我建议首先运行一条SELECT
语句来检查一条记录是否已经存在,并INSERT
仅在需要时运行。这避免了在数据库端产生错误。此外,它比 using 准确得多INSERT IGNORE
,后者基本上忽略了插入期间发生的所有错误(错误的数据类型或长度,不可为空的值,...):因此,它通常不是检查的好工具单一性。
推荐阅读
- tensorflow - 为什么`tf.train.Optimizer().compute_gradients(loss)`也返回不在`loss`子图中的变量?
- linux - Android Studio 3.2.1 - 无法将项目与 gradle 文件同步:@NotNull 参数“消息”的参数......不能为空
- r - 如何在不重复变量的情况下合并两个具有共享案例和变量的数据集?
- rest - 你知道 Nestjs BE nodejs 框架的任何 REST 生成器吗?
- docusignapi - 没有签名者姓名的 Docusign 信封创建
- sql - 从 SQL 查询中添加缺失的日期
- jupyter-notebook - 通过 Jupyter 内核(Jupyter Notebook 扩展)执行代码时等待内核准备就绪
- python - Celery-Progress-Bar 在 Django 中不起作用
- c# - 如何解决 Microsoft.Windows.Storage.StorageException:无法解析远程名称
- excel - Excel VBA 对于范围内的每个单元格似乎多次通过同一个单元格