【问题标题】:Reset rowid field after deleting rows删除行后重置 rowid 字段
【发布时间】:2018-02-20 07:17:32
【问题描述】:

我正在使用 sqlite 数据库,我想在删除行后重置 rowid 字段。我的表没有主键或指定的 Id,我只使用 sqlite 给出的默认 rowid。

  NOM        TYPE     CL     VAL   SP        TP

 "test1"    "test1"  "1"    "1"  "test1"    "test1"
 "test2"    "test2"  "2"    "2"  "test2"    "test2"
 "test3"    "test3"  "3"    "3"  "test3"    "test3"

当我删除一行或多行时,我希望默认的 rowid 自动重置,所以我阅读了一些答案,发现我们可以使用 sql_sequence table 来做到这一点。

delete from sqlite_sequence where name='table_name'

问题是我在我的 sqlite 中找不到那个表

[ no such table: sqlite_sequence ]

有什么办法可以解决我的问题

【问题讨论】:

    标签: sqlite rowid


    【解决方案1】:

    默认情况下,表将具有不使用 sqlite_sequence 表的 rowid

    只有当 rowid 的别名被指定(使用column_name INTEGER PRIMARY KEYcolumn_name INTEGER PRIMARY KEY AUTOINCREMENT 定义)AND 时,别名的定义才包含可选的@ 987654328@ 关键字/短语,确定 rowid 的算法利用 sqlite_sequence 表来确保 rowid 大于上次使用的 rowid(通常无论如何都会更大)。

    即使您使用了AUTOINCREMENT,因此 sqlite_sequence 表存在并且您从 sqlite_sequence 表中删除了该表的行。这不会重置序列,因为我相信使用的算法使用表中现有的最高 rowid 和从 sqlite_sequence 表中获得的值中的较高者。 here's a post I made in realtion to this

    使用 rowid 的理由可能很少或根本没有,就好像它不是唯一标识行的方法一样。

    但是,如果您真的想管理 rowid,那么您可以通过指定 rowid 列来专门设置此值(注意有一个隐含的 UNIQUE 约束)。

    所以你可以例如使用:-

    INSERT INTO yourtable (rowid, NOM, TYPE, CL, VAL, SP, TP) VALUES(123,'MyName','Testx', '123', '123', 'Testx', 'Testx');
    
    • rowid 将设置为 123

    您也可以使用更新 rowid,例如:-

    UPDATE yourtable SET rowid = 5 WHERE rowid = 123;
    

    - 123 的 rowid 更改为 5 允许唯一约束

    您可以使用以下方法获得最高的 rowid:-

    SELECT max(rowid) from yourtable;
    

    你甚至可以使用:-

    INSERT INTO yourtable (rowid, NOM, TYPE, CL, VAL, SP, TP) VALUES((SELECT max(rowid) from yourtable)+1,'MyName','maxx', '???', '???', 'Maxx', 'Maxx');
    
    • 插入下一个 rowid 序列。

    请注意,上面的示例没有 rowid 的别名,显然它们不依赖于不存在的 sqlite_sequence 表。

    当然,您总是可以拥有自己的 sqlite_sequence 表,只是它不能命名为这个,也不能以 sqlite 开头。 注意!这将是使用 SQLite 重置 id 的唯一持久方法,但可能是一场噩梦


    以上所有假设:-

    我想在删除行后重置 rowid 字段

    不是......在删除所有行之后,就好像在这种情况下,rowid 将被有效重置(基本上没有 AUTOINCREMENT rowid 是根据现有 rowid 的最高值确定的,因此,如果不存在,则 rowid 将为 1)。

    • 请参见下面的示例 2。

    注意!!

    此答案不宽恕或推荐上述任何内容。


    示例 1

    使用以下内容:-

    CREATE TABLE IF NOT EXISTS rowidtable (NOM TEXT, TYPE TEXT, CL TEXT, VAL TEXT, SP TEXT, TP TEXT);
    INSERT INTO rowidtable (rowid) VALUES(10);
    INSERT INTO rowidtable (rowid) VALUES(12);
    INSERT INTO rowidtable (rowid, NOM, TYPE, CL, VAL, SP, TP) VALUES(123,'MyName','Testx', '123', '123', 'Testx', 'Testx');
    INSERT INTO rowidtable (NOM, TYPE, CL, VAL, SP, TP) VALUES('MyName','Testx', '123', '123', 'Testx', 'Testx');
    UPDATE rowidtable SET rowid = 5 WHERE rowid = 123;
    SELECT max(rowid) from rowidtable;
    --// Following repteated 3 times (so rowid's 125,126 and 127 used respectively)
    INSERT INTO rowidtable (rowid, NOM, TYPE, CL, VAL, SP, TP) VALUES((SELECT max(rowid) from rowidtable)+1,'MyName','maxx', '???', '???', 'Maxx', 'Maxx');
    select rowid,* from rowidtable;
    

    结果表是:-

    • id 为 1012 的行首先插入(空值(红色)表示其他值)
    • ID 为 5 的行最初是 ID 为 123 的行
    • ID 为 125126127 的行是使用通过子查询获得的 rowid 插入的,该子查询将当前最大 rowid 加 1 (即最后一次插入运行 3 次)。

    示例 2

    如果使用以下内容:-

    DELETE from rowidtable
    INSERT INTO rowidtable (NOM) VALUES('after mass delete');
    

    那么结果表将是:-

    【讨论】:

      【解决方案2】:

      sqlite_sequence 表仅用于定义了 INTEGER PRIMARY KEY AUTOINCREMENT 列的表。

      如果您依赖表中给定行的内部默认值rowid,那么您应该为该表定义一个命名的自动增量主键,然后您可以使用sqlite_sequence 表重置计数器.

      【讨论】:

        【解决方案3】:

        感谢您的所有回答,我找到了我想要的东西,而且很简单

        DELETE FROM 'table_name' WHERE col='value';
        REINDEX 'table_name';
        

        这将重建指定的表索引,所以如果所有行都被删除,则索引重置为0,如果仍然是表中的行,则索引将被正确重新排序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          • 2018-02-07
          • 2022-11-21
          • 1970-01-01
          • 2011-02-05
          • 2012-04-11
          相关资源
          最近更新 更多