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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 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


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
SQL 存储 关系型数据库
MySQL not exists 真的不走索引么
MySQL not exists 真的不走索引么
30 0
|
3月前
|
SQL 人工智能 关系型数据库
mysql中in 和exists的区别
mysql中in 和exists的区别
|
7月前
|
关系型数据库 MySQL
【mysql】快速使用mysql exists 语法
【mysql】快速使用mysql exists 语法
47 1
|
3月前
|
SQL 关系型数据库 MySQL
MySQL技能完整学习列表3、SQL语言基础——1、SQL(Structured Query Language)简介——2、基本SQL语句:SELECT、INSERT、UPDATE、DELETE
MySQL技能完整学习列表3、SQL语言基础——1、SQL(Structured Query Language)简介——2、基本SQL语句:SELECT、INSERT、UPDATE、DELETE
54 0
|
5月前
|
SQL 关系型数据库 MySQL
MySQL 中exists与in及any的用法详解
MySQL 中exists与in及any的用法详解
60 3
|
2月前
|
关系型数据库 MySQL
922.【mysql】if 函数
922.【mysql】if 函数
20 3
|
4月前
|
存储 SQL 关系型数据库
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
MySQL存储过程 if、case、while、loop、游标、变量、条件处理程序
49 0
|
5月前
|
关系型数据库 MySQL
零基础带你学习MySQL—Insert语句以及注意事项(七)
零基础带你学习MySQL—Insert语句以及注意事项(七)
|
7月前
|
关系型数据库 MySQL
MySQL安装--显示sever name has already exists
MySQL安装--显示sever name has already exists
|
9月前
|
关系型数据库 MySQL 数据库
数据的查询与添加:解析MySQL中的SELECT和INSERT操作
在数据库管理中,SELECT和INSERT操作是日常工作中的重要环节,用于数据的获取和添加。了解如何正确使用这两个操作是数据库操作的关键。
135 0