MySql可以悄悄放弃外键失败的插入吗?

时间:2013-03-28 13:51:15

标签: mysql sql

我正在执行INSERT INTO Foo VALUES (a, b, c, ...),有时其中一个ab等不满足外键约束。

在这种情况下,我希望不会发生插入,也不会产生错误。

我可以在一个声明中执行此操作,还是必须单独执行IF EXISTS

3 个答案:

答案 0 :(得分:6)

是的,使用ignore关键字:

INSERT IGNORE INTO `foo` (...) VALUES (...);
  

如果使用IGNORE关键字,则执行时会出现错误   INSERT语句被视为警告。例如,没有   IGNORE,一个复制现有UNIQUE索引或PRIMARY KEY的行   表中的值导致重复键错误,语句为   中止。使用IGNORE时,仍未插入行,但没有错误   发出的。

另一方面,如果你担心的是你在父母行之前插入孩子,你也可以禁用约束并在插入父母后启用它们:

SET FOREIGN_KEY_CHECKS=0;

-- do your inserts not caring about foreign keys

SET FOREIGN_KEY_CHECKS=1;

但这只有在您知道时才尊重数据完整性。


另外,我认为值得在mysql网站上添加关于deferring constraints的评论:

  

与MySQL一般,在插入,删除或删除的SQL语句中   更新许多行,InnoDB检查UNIQUE和FOREIGN KEY约束   行由行。执行外键检查时,InnoDB设置共享   它必须查看的子记录或父记录上的行级锁定。 InnoDB的   立即检查外键约束;支票不会延期   到事务提交。根据SQL标准,默认   行为应该推迟检查。也就是说,只有约束   在处理完整个SQL语句后检查。直到   InnoDB实现了延迟约束检查,有些事情将是   不可能,例如删除使用a引用自身的记录   外键。

我们知道MySQL innoDB将来也可以实现这个功能。

答案 1 :(得分:0)

如果您可以完全控制插入的SQL结构,可以尝试这样的操作:

insert into Foo (a, b, c)
select
    x.a,
    x.b,
    x.c
from 
    (select
        101 as a,
        202 as b,
        'ABC123' as c
    from dual ) x
    inner join other_table y
        on x.b = y.pkid

在这种情况下,由于您正在对数据及其父表执行内部联接,如果数据中的外键值在主表中没有相应的值,则不会插入任何内容。

答案 2 :(得分:0)

最好的方法是使用:

INSERT INTO table (col1, col2) SELECT val1, val2 FROM table2 WHERE val3 = 123

WHERE部分结果为false时,则不会执行整个INSERT。同时SELECT val1, val2可以包含您想要的任何子查询。

在您的情况下,您可能会检查WHERE条件中是否存在外键。

有关详细说明,请参阅MySQL INSERT IF (custom if statements)