MySQL防止重複插入相同記錄 insert if not exists

琦彥發表於2018-03-21
        在 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


相關文章