SQLite起始rowid为0

时间:2016-01-27 16:47:11

标签: python-2.7 sqlite auto-increment

我正在尝试设置一个SQLite表,其中rowid从0开始而不是默认值1.最终目标是能够运行第一个INSERT语句并将其插入到rowid 0.将rowid显式设置为0表示第一个INSERT不是一个选项。

我尝试了一些与AUTOINCREMENT有关的事情但是没有任何运气让这个干净利落。我找到的唯一成功方法是插入一个rowid为-1的行,然后再删除它。这有效,但它很乱,我想找到一种更干净的方式。我在Python 2.7中使用内置的sqlite3库。

底线问题:

除了手动插入-1值然后稍后删除之外,是否有更简洁的方法从0开始rowid?

一些辅助信息:

我在这里发现了一个类似的问题并使用了一些AUTOINCREMENT设置:Set start value for AUTOINCREMENT in SQLite

sqlite_sequence表似乎不适用于负数。我用以下方法测试它:

import sqlite3
con = sqlite3.Connection('db.db')
cur = con.cursor()

cur.execute("CREATE TABLE test(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)")
cur.execute("INSERT INTO sqlite_sequence (name,seq) VALUES (?,?)", ('test',-1))
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 1
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 2
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 3

cur.execute("SELECT rowid, id, val FROM test")
print cur.fetchall()

将-1插入sqlite_sequence时,应将下一个rowid设置为0,但它使用的是1。如果sqlite_sequence初始化为正数,则rowid符合预期。

import sqlite3
con = sqlite3.Connection('db.db')
cur = con.cursor()

cur.execute("CREATE TABLE test(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)")
cur.execute("INSERT INTO sqlite_sequence (name,seq) VALUES (?,?)", ('test',10))
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 11
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 12
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 13

cur.execute("SELECT rowid, id, val FROM test")
print cur.fetchall()

自动增量不支持这样的负数吗?我在SQLite文档中找不到任何提及它。

2 个答案:

答案 0 :(得分:1)

documentation表示,使用AUTOINCREMENT,

  

为新行选择的ROWID至少比同一个表中以前存在的最大ROWID大一个。

因此,该算法不仅可以查看sqlite_sequence表中的值,还可以查看表中的最后一行,并使用这两个值中的较大值。

当表为空时,假设最大的实际rowid为零。这样做是为了使第一个插入的rowid变为1

因此,生成小于一的rowid的唯一方法是在表中已经有另一行。

答案 1 :(得分:0)

我在java中使用sqlite并且无意中第一行有ROWID = 0。

这是代码

    long dbid = getDbid();
    ContentValues values = new ContentValues();
    values.put(KEY_ROWID, dbId); // Line that cause ROWID == 0 when dbid == 0
    values.put(KEY_KEY, key);
    values.put(KEY_VALUE, value);
    if (dbId == 0) {
        dbId = dbase.insert(PREFERENCES_TABLE, null, values);
        map_.put(key, new Pair<>(dbId, value));
    }
    else
        dbase.update(PREFERENCES_TABLE, values, KEY_ROWID + "=" + dbId, null);

意图是将零作为未初始化的值,但插入返回零。我不希望第一个ROWID等于零,所以我删除了行并插入了返回的行。