处理有关批量插入中重复行的反馈

时间:2019-03-04 23:26:08

标签: php mysql regex

我有一项服务,除填写表格外,用户还可以一次导入多个项目,并上传csv文件,其中每一行代表一个项目-实体使用在我的mysql数据库的唯一字段下设置的ID(仅可以存在一个具有特定ID的项目。

当用户完成上载和csv处理后,我想提供有关其文件中哪些项目已经存在于数据库中的反馈。我决定使用INSERT IGNORE,从警告(regex)中解析出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.

1 个答案:

答案 0 :(得分:1)

使用preg_match

preg_match(
    "/Duplicate entry '(\d+)' for key 'id'/", 
    $duplicated_item['Message'], 
    $result
);
$id[$duplicates_count] = $result[1];

(\d+)代表应捕获的数字序列(\d)(括号内)。


但是,如果您可以控制数据导入的方式,则有更好的处理方法。首先,我建议首先运行SELECT语句以检查记录是否已存在,并仅在需要时运行INSERT。这样可以避免在数据库端产生错误。而且,它比使用INSERT IGNORE更准确,// yourEventService.js class YourEventService { listeners = [] subscribe = listener => this.listeners.push(listener) unsubscribe = listener => this.listeners = this.listeners.filter(item => item !== listener) emit = message => listener.forEach(listener => listener(message)) } export default new YourEventService() // singleton export // someWhereElse.js import yourEventService from './yourEventService' window.addEventListener('click', () => yourEventService.emit('myNewGroup')) // it's just an event example //component.js, sorry I don't know how to typescript well import yourEventService from './yourEventService' export default class PopupChatRoot extends React.Component { state = { groupId: this.props.group; // initial value is passed by props } componentDidMount() { yourEventService.subscribe(this.handleMessage) } componentWillUnmount() { yourEventService.unsubscribe(this.handleMessage) } handleMessage = message => { this.setState({ groupId: message }) } render() { return ( <div className="modal-body"> <p>{this.state.groupId}</p> </div> ); } } const component = document.getElementById('popupChatComponent'); if (component) { const props = Object.assign({}, component.dataset); render(<PopupChatRoot {...props}/>, component); } 基本上会忽略插入过程中发生的 all 错误(错误的数据类型或长度,不可为空的值,...):为此因此,通常不是检查统一性的好工具。