Use INSERT IGNORE INTO table
.
还有INSERT … ON DUPLICATE KEY UPDATE
语法,您可以在中找到解释13.2.6.2 INSERT ... ON DUPLICATE KEY UPDATE 语句 https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html.
发帖自bogdan.org.ua https://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html根据谷歌的网络缓存 https://web.archive.org/web/20191028155933/http://webcache.googleusercontent.com/search?q=cache:bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html:
2007 年 10 月 18 日
首先:从最新的 MySQL 开始,标题中提供的语法不是
可能的。但有几种非常简单的方法可以实现
预期使用现有功能。
有 3 种可能的解决方案:使用 INSERT IGNORE、REPLACE 或
在重复密钥更新时插入...。
假设我们有一张桌子:
CREATE TABLE `transcripts` (
`ensembl_transcript_id` varchar(20) NOT NULL,
`transcript_chrom_start` int(10) unsigned NOT NULL,
`transcript_chrom_end` int(10) unsigned NOT NULL,
PRIMARY KEY (`ensembl_transcript_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
现在想象我们有一个自动导入转录本的管道
来自 Ensembl 的元数据,并且由于各种原因管道
可能在执行的任何步骤中被破坏。因此,我们需要保证两个
事物:
- 管道的重复执行不会破坏我们的
> 数据库
- 重复处决不会因为“重复”而死亡
> 主键错误。
方法一:使用REPLACE
这很简单:
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
如果记录存在,则覆盖;如果还没有
存在,就会被创建。然而,使用这种方法效率不高
对于我们的情况:我们不需要覆盖现有记录,这很好
只是为了跳过它们。
方法2:使用INSERT IGNORE 也很简单:
INSERT IGNORE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
在这里,如果“ensembl_transcript_id”已经存在于
数据库,它将被默默地跳过(忽略)。 (更准确地说,
这里引用 MySQL 参考手册:“如果你使用 IGNORE
关键字,执行 INSERT 语句时发生的错误是
而是将其视为警告。例如,如果没有 IGNORE,则该行
复制表中现有的 UNIQUE 索引或 PRIMARY KEY 值
导致重复键错误并且语句被中止。”。)如果
记录尚不存在,将被创建。
第二种方法有几个潜在的缺点,包括
如果发生任何其他问题,查询不会中止(请参阅
手动的)。因此,如果之前没有进行过测试,则应使用它
忽略关键字。
方法 3:使用 INSERT … ON DUPLICATE KEY UPDATE:
第三个选项是使用INSERT … ON DUPLICATE KEY UPDATE
语法,并且在 UPDATE 部分只是什么都不做,做一些无意义的事情
(空)运算,例如计算 0+0(Geoffray 建议执行以下操作)
id=id 分配让 MySQL 优化引擎忽略这一点
手术)。这种方法的优点是它只忽略重复的
关键事件,并且仍然因其他错误而中止。
最后声明:这篇文章的灵感来自 Xaprb。我还建议
请参阅他关于编写灵活的 SQL 查询的另一篇文章。