在执行包含许多行的INSERT语句时,我希望跳过重复的条目,否则会导致失败。经过一番研究,我的选择似乎是使用任何一种:
ON DUPLICATE KEY UPDATE,这意味着在某些代价下进行不必要的更新,或者 INSERT IGNORE暗示着邀请其他类型的失败在未通知的情况下潜入。
我的这些假设对吗?简单地跳过可能导致重复的行并继续到其他行,最好的方法是什么?
在执行包含许多行的INSERT语句时,我希望跳过重复的条目,否则会导致失败。经过一番研究,我的选择似乎是使用任何一种:
ON DUPLICATE KEY UPDATE,这意味着在某些代价下进行不必要的更新,或者 INSERT IGNORE暗示着邀请其他类型的失败在未通知的情况下潜入。
我的这些假设对吗?简单地跳过可能导致重复的行并继续到其他行,最好的方法是什么?
当前回答
除此之外。如果在同一个语句中同时使用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';
其他回答
如果使用插入忽略有一个显示警告;语句将显示一个包含所有警告的表,包括哪些id是重复的。
我经常使用INSERT IGNORE,这听起来也正是您正在寻找的那种行为。只要知道不会插入会导致索引冲突的行,并且相应地规划程序,就不应该造成任何麻烦。
ON DUPLICATE KEY UPDATE并不是真正的标准。它和REPLACE一样标准。参见SQL MERGE。
实际上,这两个命令都是标准命令的替代语法版本。
除此之外。如果在同一个语句中同时使用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';
插入忽略的潜在危险。 如果您试图插入VARCHAR值的时间比列定义的时间长-即使启用了严格模式,该值也会被截断并插入。