MySQL防止重复插入相同记录 insert if not exists

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL防止重复插入相同记录 insert if not exists


在 MySQL 中,插入(insert)一条记录,经常需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作


1. INSERT INTO IF EXISTS

1.1.语法

INSERT INTO TABLE (field1, field2, fieldn) SELECT
  'field1',
  'field2',
  'fieldn'
FROM
  DUAL
WHERE
  NOT EXISTS (
    SELECT
      field
    FROM
      TABLE
    WHERE
      field = ?
  )


1.2.插入一条记录

  • 先创建一张表
CREATE TABLE `pay_namelist` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `batchno` varchar(20) DEFAULT NULL COMMENT '批次号',
  `idserial` varchar(20) DEFAULT NULL COMMENT '证件号',
  `useranme` varchar(60) DEFAULT NULL COMMENT '姓名',
  `payproid` int(11) DEFAULT NULL COMMENT '缴费项目ID',
  `subpayproid` int(11) DEFAULT NULL COMMENT '子缴费项ID',
  `impdate` datetime DEFAULT NULL COMMENT '导入时间',
  `paystatus` varchar(2) DEFAULT NULL COMMENT '支付状态 0-未缴费 1-已缴费',
  `payamt` int(11) DEFAULT NULL COMMENT '缴费金额',
  `status` varchar(2) DEFAULT NULL COMMENT '状态 0-删除 1-正常',
  `orgcode` varchar(20) DEFAULT NULL COMMENT '机构代码',
  `orderno` varchar(32) DEFAULT NULL,
  `reservestr1` varchar(200) DEFAULT NULL COMMENT '预留字段1',
  `reservestr2` varchar(200) DEFAULT NULL COMMENT '预留字段2',
  PRIMARY KEY (`id`),
  KEY `idx_paynl_idserial` (`idserial`) USING BTREE,
  KEY `idx_paynl_orderno` (`orderno`)
) ENGINE=InnoDB AUTO_INCREMENT=352119 DEFAULT CHARSET=utf8 COMMENT='缴费人员名单';


在pay_namelist重复插入相同的一条数据

INSERT INTO pay_namelist (
  `batchno`,
  `idserial`,
  `useranme`,
  `payproid`,
  `subpayproid`,
  `impdate`,
  `paystatus`,
  `payamt`,
  `status`,
  `orgcode`,
  `orderno`,
  `reservestr1`,
  `reservestr2`
) SELECT
  '2018032016204085',
  '2431503022',
  'wanghan',
  '470',
  NULL,
  '2018-03-20 16:22:05',
  '0',
  '1300000',
  '1',
  '26',
  '20180320162241705',
  NULL,
  NULL
FROM
  DUAL
WHERE
  NOT EXISTS (
    SELECT
      batchno,
      payproid,
      idserial,
      payamt
    FROM
      pay_namelist
    WHERE
    batchno = '2018032016204085'
    AND payproid = '470'
    AND idserial = '161'
    AND payamt = '1300000'
  )


  • 第一次执行:Affected rows: 1,之后执行都是Affected rows: 0,说明实现了单条记录的防重插入;


1.3.插入多条记录

  • 插入多条记录,需要借助一张临时表
  • 创建临时表
CREATE TABLE `pay_namelist_temp` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `batchno` varchar(20) DEFAULT NULL COMMENT '批次号',
  `idserial` varchar(20) DEFAULT NULL COMMENT '证件号',
  `useranme` varchar(60) DEFAULT NULL COMMENT '姓名',
  `payproid` int(11) DEFAULT NULL COMMENT '缴费项目ID',
  `subpayproid` int(11) DEFAULT NULL COMMENT '子缴费项ID',
  `impdate` datetime DEFAULT NULL COMMENT '导入时间',
  `paystatus` varchar(2) DEFAULT NULL COMMENT '支付状态 0-未缴费 1-已缴费',
  `payamt` int(11) DEFAULT NULL COMMENT '缴费金额',
  `status` varchar(2) DEFAULT NULL COMMENT '状态 0-删除 1-正常',
  `orgcode` varchar(20) DEFAULT NULL COMMENT '机构代码',
  `orderno` varchar(32) DEFAULT NULL,
  `reservestr1` varchar(200) DEFAULT NULL COMMENT '预留字段1',
  `reservestr2` varchar(200) DEFAULT NULL COMMENT '预留字段2',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=352124 DEFAULT CHARSET=utf8 COMMENT='缴费人员名单';
  • 在临时表插入8条记录
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '106', '测6', '276', NULL, '2017-12-25 11:09:18', '0', '1', '1', '89', '20171225110917911', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '105', '测5', '276', NULL, '2017-12-25 11:09:18', '1', '1', '1', '89', '20171225110917914', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '107', '测7', '276', NULL, '2017-12-25 11:09:18', '1', '1', '1', '89', '20171225110917917', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '102', '测2', '276', NULL, '2017-12-25 11:09:18', '0', '1', '1', '89', '20171225110917920', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '103', '测3', '276', NULL, '2017-12-25 11:09:18', '0', '1', '1', '89', '20171225110917923', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '108', '测8', '276', NULL, '2017-12-25 11:09:18', '0', '1', '1', '89', '20171225110917925', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '104', '测4', '276', NULL, '2017-12-25 11:09:18', '1', '1', '1', '89', '20171225110917928', NULL, NULL);
INSERT INTO pay_namelist_temp ( `batchno`, `idserial`, `useranme`, `payproid`, `subpayproid`, `impdate`, `paystatus`, `payamt`, `status`, `orgcode`, `orderno`, `reservestr1`, `reservestr2`) VALUES ( '201712251109117', '101', '测1', '276', NULL, '2017-12-25 11:09:18', '1', '1', '1', '89', '20171225110917930', NULL, NULL);
  • 在pay_namelist重复插入相同的多条数据
INSERT INTO pay_namelist (
  `batchno`,
  `idserial`,
  `useranme`,
  `payproid`,
  `subpayproid`,
  `impdate`,
  `paystatus`,
  `payamt`,
  `status`,
  `orgcode`,
  `orderno`,
  `reservestr1`,
  `reservestr2`
) SELECT
  `batchno`,
  `idserial`,
  `useranme`,
  `payproid`,
  `subpayproid`,
  `impdate`,
  `paystatus`,
  `payamt`,
  `status`,
  `orgcode`,
  `orderno`,
  `reservestr1`,
  `reservestr2`
FROM
  pay_namelist_temp
WHERE
  NOT EXISTS (
    SELECT
      batchno,
      payproid,
      idserial,
      payamt
    FROM
      pay_namelist
    WHERE
    pay_namelist.batchno = pay_namelist_temp.batchno
    AND pay_namelist.payproid = pay_namelist_temp.payproid
    AND pay_namelist.idserial = pay_namelist_temp.idserial
    AND pay_namelist.payamt = pay_namelist_temp.payamt
  )
  • 第一次执行:Affected rows: 1,之后执行都是Affected rows: 0,说明实现了单条记录的防重插入;


2.唯一性约束

https://blog.csdn.net/fly910905/article/details/79693070


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
关系型数据库 MySQL 索引
mysql中EXISTS用法注意点
mysql中EXISTS用法注意点
|
7月前
|
SQL 关系型数据库 MySQL
MySQL数据库子查询练习——EXISTS(存在)
MySQL数据库子查询练习——EXISTS(存在)
87 1
|
4月前
|
SQL 存储 关系型数据库
MySQL in和exists的取舍
本文讨论了SQL查询中IN和EXISTS的使用场景及其区别。IN适用于外表大而内表小的情况,会将子查询结果存储在临时表中;EXISTS则以外表为驱动表,适合外表小而内表大的情况,且不生成临时表。结论是:当子查询数据量大时,应使用EXISTS。
113 8
|
5月前
|
存储 自然语言处理 关系型数据库
MySQL全文索引源码剖析之Insert语句执行过程
【8月更文挑战第17天】在MySQL中,处理含全文索引的`INSERT`语句涉及多步骤。首先进行语法解析确认语句结构无误;接着语义分析检查数据是否符合表结构及约束。随后存储引擎执行插入操作,若涉及全文索引则进行分词处理,并更新倒排索引结构。此外,事务管理确保了操作的完整性和一致性。通过示例创建含全文索引的表并插入数据,可见MySQL如何高效地处理此类操作,有助于优化数据库性能和提升全文搜索效果。
|
5月前
|
SQL 存储 关系型数据库
MySQL in和exists的取舍
介绍了SQL中`in`与`exists`的选择策略:`in`适用于外表大而内表小的情况,先执行子查询并存储结果,再遍历外表匹配;`exists`则以外层表为驱动,适合外表小而内表大的场景,直接检查内表是否存在匹配项,无需创建临时表。选择依据为表大小及查询效率。
|
5月前
|
关系型数据库 MySQL
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
392 2
|
5月前
|
SQL 关系型数据库 MySQL
在 MySQL 中使用 Exists
【8月更文挑战第11天】
642 0
在 MySQL 中使用 Exists
|
5月前
|
存储 关系型数据库 MySQL
在 MySQL 中使用 Insert Into Select
【8月更文挑战第11天】
882 0
在 MySQL 中使用 Insert Into Select
|
7月前
|
存储 SQL 关系型数据库
MySQL存储过程——if判断示例
MySQL存储过程——if判断示例
107 0
|
7月前
|
SQL 安全 关系型数据库
MySQL DML语句insert全表数据添加语句以及注意事项
MySQL DML语句insert全表数据添加语句以及注意事项
64 0