在执行包含许多行的INSERT语句时,我希望跳过重复的条目,否则会导致失败。经过一番研究,我的选择似乎是使用任何一种:
ON DUPLICATE KEY UPDATE,这意味着在某些代价下进行不必要的更新,或者 INSERT IGNORE暗示着邀请其他类型的失败在未通知的情况下潜入。
我的这些假设对吗?简单地跳过可能导致重复的行并继续到其他行,最好的方法是什么?
在执行包含许多行的INSERT语句时,我希望跳过重复的条目,否则会导致失败。经过一番研究,我的选择似乎是使用任何一种:
ON DUPLICATE KEY UPDATE,这意味着在某些代价下进行不必要的更新,或者 INSERT IGNORE暗示着邀请其他类型的失败在未通知的情况下潜入。
我的这些假设对吗?简单地跳过可能导致重复的行并继续到其他行,最好的方法是什么?
当前回答
如果要在表中插入与之冲突的主键或唯一索引,它将更新冲突的行,而不是插入该行。
语法:
insert into table1 set column1 = a, column2 = b on duplicate update column2 = c;
现在在这里,这个插入语句看起来可能与您之前看到的不同。此插入语句试图将table1中值为a和b的行分别插入列columnn1和column2。
让我们深入理解这句话:
例如:这里的column1被定义为table1中的主键。
现在,如果在table1中,column n1中没有值为“a”的行。因此,这条语句将在table1中插入一行。
现在,如果在table1中,在column2中有一行值为“a”。因此,这条语句将用“c”更新行column2的值,其中columnn1的值为“a”。
因此,如果你想插入一个新行,否则更新该行冲突的主键或唯一索引。 在这个链接上阅读更多
其他回答
ON DUPLICATE KEY UPDATE并不是真正的标准。它和REPLACE一样标准。参见SQL MERGE。
实际上,这两个命令都是标准命令的替代语法版本。
替换成似乎是一个选择。或者你可以查一下
IF NOT EXISTS(QUERY) Then INSERT
这将插入或删除然后插入。我倾向于先进行IF NOT EXISTS检查。
需要补充的重要一点是:当使用INSERT IGNORE时,如果你确实违反了键,MySQL不会发出警告!
如果您尝试一次插入100条记录,其中有一条错误,您将进入交互模式:
查询OK,影响99行(0.04秒) 记录:100重复:1警告:0
如你所见:没有警告!这种行为甚至在Mysql官方文档中都有错误的描述。
如果你的脚本需要被告知,如果一些记录没有被添加(由于键违反),你必须调用mysql_info()并解析它的“duplicate”值。
如果要在表中插入与之冲突的主键或唯一索引,它将更新冲突的行,而不是插入该行。
语法:
insert into table1 set column1 = a, column2 = b on duplicate update column2 = c;
现在在这里,这个插入语句看起来可能与您之前看到的不同。此插入语句试图将table1中值为a和b的行分别插入列columnn1和column2。
让我们深入理解这句话:
例如:这里的column1被定义为table1中的主键。
现在,如果在table1中,column n1中没有值为“a”的行。因此,这条语句将在table1中插入一行。
现在,如果在table1中,在column2中有一行值为“a”。因此,这条语句将用“c”更新行column2的值,其中columnn1的值为“a”。
因此,如果你想插入一个新行,否则更新该行冲突的主键或唯一索引。 在这个链接上阅读更多
除此之外。如果在同一个语句中同时使用INSERT IGNORE和ON DUPLICATE KEY UPDATE,如果插入发现重复的键,更新仍然会发生。换句话说,更新优先于忽略。但是,如果ON DUPLICATE KEY UPDATE子句本身导致重复键错误,则该错误将被忽略。
如果您有多个唯一键,或者您的更新试图违反外键约束,就会发生这种情况。
CREATE TABLE test
(id BIGINT (20) UNSIGNED AUTO_INCREMENT,
str VARCHAR(20),
PRIMARY KEY(id),
UNIQUE(str));
INSERT INTO test (str) VALUES('A'),('B');
/* duplicate key error caused not by the insert,
but by the update: */
INSERT INTO test (str) VALUES('B')
ON DUPLICATE KEY UPDATE str='A';
/* duplicate key error is suppressed */
INSERT IGNORE INTO test (str) VALUES('B')
ON DUPLICATE KEY UPDATE str='A';