我正在尝试设置一个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文档中找不到任何提及它。
答案 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等于零,所以我删除了行并插入了返回的行。