在执行包含许多行的INSERT语句时,我希望跳过重复的条目,否则会导致失败。经过一番研究,我的选择似乎是使用任何一种:

ON DUPLICATE KEY UPDATE,这意味着在某些代价下进行不必要的更新,或者 INSERT IGNORE暗示着邀请其他类型的失败在未通知的情况下潜入。

我的这些假设对吗?简单地跳过可能导致重复的行并继续到其他行,最好的方法是什么?


当前回答

插入忽略的潜在危险。 如果您试图插入VARCHAR值的时间比列定义的时间长-即使启用了严格模式,该值也会被截断并插入。

其他回答

如果使用插入忽略有一个显示警告;语句将显示一个包含所有警告的表,包括哪些id是重复的。

需要补充的重要一点是:当使用INSERT IGNORE时,如果你确实违反了键,MySQL不会发出警告!

如果您尝试一次插入100条记录,其中有一条错误,您将进入交互模式:

查询OK,影响99行(0.04秒) 记录:100重复:1警告:0

如你所见:没有警告!这种行为甚至在Mysql官方文档中都有错误的描述。

如果你的脚本需要被告知,如果一些记录没有被添加(由于键违反),你必须调用mysql_info()并解析它的“duplicate”值。

插入……ON DUPLICATE KEY UPDATE优先用于防止意外异常管理。

当您只有**1个唯一约束时,此解决方案才有效

在我的例子中,我知道col1和col2组成了一个唯一的综合指数。

它会跟踪错误,但不会对副本抛出异常。 关于性能,相同值的更新是有效的,因为MySQL注意到这一点,并且不更新它

INSERT INTO table
  (col1, col2, col3, col4)
VALUES
  (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
    col1 = VALUES(col1),
    col2 = VALUES(col2)

使用这种方法的想法来自phpdelusions.net/pdo上的评论。

如果要在表中插入与之冲突的主键或唯一索引,它将更新冲突的行,而不是插入该行。

语法:

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”。

因此,如果你想插入一个新行,否则更新该行冲突的主键或唯一索引。 在这个链接上阅读更多

插入忽略的潜在危险。 如果您试图插入VARCHAR值的时间比列定义的时间长-即使启用了严格模式,该值也会被截断并插入。