【问题标题】:Set start value for AUTOINCREMENT in SQLite在 SQLite 中设置 AUTOINCREMENT 的起始值
【发布时间】:2010-10-16 02:59:33
【问题描述】:

如何在 SQLite 中设置 AUTOINCREMENT 字段的起始值?

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    来自SQLite web site

    SQLite 使用特殊的SQLITE_SEQUENCE 表来跟踪表所拥有的最大 ROWID。每当创建包含 AUTOINCREMENT 列的普通表时,就会自动创建和初始化 SQLITE_SEQUENCE 表。 SQLITE_SEQUENCE 表的内容可以使用普通的 UPDATE、INSERT 和 DELETE 语句进行修改。 但修改此表可能会干扰 AUTOINCREMENT 密钥生成算法。在进行此类更改之前,请确保您知道自己在做什么。

    我试过了,效果很好:

    UPDATE SQLITE_SEQUENCE SET seq = <n> WHERE name = '<table>'
    

    n+1 是你想要的下一个 ROWID,table 是表名。

    【讨论】:

    • 不确定,因为我不确定 sqlite 内部是如何工作的。值得注意的是,jle 和我上面的建议是 PHP 的 MDB2 库如何支持更改 id。看看他们的 sqlite 驱动源码:cvs.php.net/viewvc.cgi/pear/MDB2/MDB2/Driver/…
    • 诚信不是问题(我认为,不是专家或任何东西)。我相信他们警告的问题是,如果您删除 ID 小于 MAX(ID) 的行并尝试以这种方式手动设置自动增量。由于违反主键,您将在插入第一行后卡住。
    • 确切的算法记录在链接页面上,不会在任何 3.x 版本中更改以保持兼容性。
    • 完美!简单而优雅的解决方案。
    • 唯一的问题是,如果在 sqlite_sequence 中还没有表的条目,这将不起作用。正确方法见 iTech 的回答。
    【解决方案2】:

    value-1 显式插入表中,然后删除该行。

    编辑:下一条评论,讨论直接编辑SQLITE_SEQUENCE 表可能更可取:https://stackoverflow.com/a/692871/10093

    【讨论】:

    • 我想这是最好的方法,但它并不漂亮。
    • 这对我不起作用。如果我有一个只有 1 个条目(id 1)的表“用户”,而自动增量为 3,则插入另一个用户 id -1 然后删除,下一个插入的用户仍然是 id 4(firefox 的 SQLite 管理器扩展,如果它有所作为)
    • 似乎是一种解决方法。我更喜欢处理相关表的 sqlite_sequence 表记录。
    【解决方案3】:

    我正在使用下面的查询来解决当 sqlite_sequence 没有表记录时的问题(即第一条记录尚未添加到表中),否则它会更新序列。

    BEGIN TRANSACTION;
    
    UPDATE sqlite_sequence SET seq = <n> WHERE name = '<table>';
    
    INSERT INTO sqlite_sequence (name,seq) SELECT '<table>', <n> WHERE NOT EXISTS 
               (SELECT changes() AS change FROM sqlite_sequence WHERE change <> 0);
    COMMIT;
    

    【讨论】:

    • 这是这里唯一完全正确的解决方案。不过,巫毒教的变化让我的眼睛流泪了;)
    • 这里为什么使用'changes()'?你不能这样做:WHERE NOT EXISTS SELECT name from sqlite_sequence WHERE name = 'table'
    【解决方案4】:

    一种方法是插入第一行明确指定要开始的行 ID。然后 SQLite 将插入高于前一个最高值的行 ID。

    【讨论】:

      【解决方案5】:

      在使用 SQLITE_SEQUENCE 表的解决方案中,该表的条目似乎是在第一次插入具有自动增量列的表之后添加的。在某些情况下,这可能会导致问题(即自动增量仍然从 1 开始,而不是从想要的值开始)。

      【讨论】:

        【解决方案6】:

        只是想为 iTech 非常感谢的回答添加一些注释:

        • sqlite_sequence 中的名称列区分大小写。 (也许只有我一个人,但来自其他数据库的我总是认为字符串比较不区分大小写)。
        • SQLite 似乎很健壮:如果 sqlite_sequence 中的数字错误并导致重复的 rowid 值,sqlite 将使用下一个可用数字作为 rowid(使用 sqlite 3.28 检查)
        • 如果 sqlite_sequence 中的行被删除也是如此。
        • 我按照评论中的建议使用“WHERE NOT EXISTS SELECT name from sqlite_sequence WHERE name = 'table'”而不是检查“changes()”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-09
          • 2014-02-17
          • 1970-01-01
          • 1970-01-01
          • 2012-12-19
          相关资源
          最近更新 更多