【问题标题】:Any way to prevent AUTOINCREASE on failed 'INSERT OR IGNORE'?有什么方法可以防止“插入或忽略”失败时自动增加?
【发布时间】:2016-09-05 08:25:09
【问题描述】:

问题摘要:使用 MySQL 和 SQLite,在具有 AUTOINCREMENT 的表上失败的INSERT OR IGNORE 仍然增加自动增量值。此处已对此进行了讨论:INSERT IGNORE increases auto increment counter even no record is added?

我的问题:99% 插入失败的表最终会产生巨大的索引号,例如记录 1500 的索引为 165200。

这是不切实际的,所以我正在寻找一种方法来对抗这种行为。

由于INSERT OR IGNORE 应该与INSERT ON CONFLICT IGNORE 相同,所以我想到了使用INSERT ON CONFLICT FAILINSERT ON CONFLICT ABORT

我的问题是我以这种方式从SELECT 插入:

INSERT OR IGNORE INTO t1 (x,y,z,) SELECT * FROM t2

此语法不接受ON CONFLICT FAIL这两个都没有

INSERT ON CONFLICT FAIL INTO t1 (x,y,z,) SELECT * FROM t2

INSERT INTO t1 (x,y,z,) SELECT * FROM t2 ON CONFLICT FAIL

有什么想法或提示吗?

【问题讨论】:

    标签: mysql sql sqlite auto-increment


    【解决方案1】:

    首先,on conflict 仅适用于 sqlite,并且在您定义约束时使用(例如 ... primary key on conflict abort ...)。如果其中一行失败,abort 将不会插入任何行。 fail 更奇怪:如果你尝试插入 5 行,而第 3 行因为键而失败,它会插入前 2 行然后停止。简而言之:不要使用它。两个版本都与ignore 不同(至少不止一行)。

    当您插入多行时,基本上只有一种方法可以防止自动增量:不要插入表中已经存在的行。

    通常的方法是检查该行是否为自己存在而不是“懒惰”on duplicate key/ignore。例如。检查列中的重复值y

    INSERT INTO t1 (x,y,z) 
    SELECT * FROM t2 main
    where not exists (
        select * from t1 test
        where main.y = test.y);
    

    是的,我知道,这会使您的代码更长。不幸的是,您将不得不忍受这种情况。

    【讨论】:

      猜你喜欢
      • 2011-02-16
      • 2017-08-03
      • 1970-01-01
      • 2021-01-10
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      相关资源
      最近更新 更多