SQLite starting rowid of 0

℡╲_俬逩灬. 提交于 2020-12-13 10:35:37

问题


I'm trying to set up a SQLite table where the rowid starts from 0 instead of the default 1. The end goal is to be able to run the first INSERT statement and have it insert to rowid 0. Explicitly setting rowid to 0 for that first INSERT is not an option.

I've tried a few things related to AUTOINCREMENT but am not having any luck getting this to work cleanly. The only successful way I've found is to insert a row with rowid of -1 and then delete it later. This works but it's messy and I'd like to find a cleaner way of doing it. I am working in Python 2.7 with the built-in sqlite3 library.

The bottom-line question:

Is there a cleaner way to start rowid from 0 other than manually inserting a -1 value and then removing it later?


Some side information:

I found a similar question here and played with some AUTOINCREMENT settings: Set start value for AUTOINCREMENT in SQLite

The sqlite_sequence table doesn't seem to work with negative numbers. I used the following to test it:

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()

With the -1 inserted into sqlite_sequence it should set the next rowid to 0, but it's using 1 instead. If sqlite_sequence is initialized to a positive number the rowids are as expected.

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()

Does auto-increment not support negative numbers like this? I couldn't find any mention of it in the SQLite documentation.


回答1:


The documentation says that, with AUTOINCREMENT,

the ROWID chosen for the new row is at least one larger than the largest ROWID that has ever before existed in that same table.

So the algorithm looks not only at the value in the sqlite_sequence table, but also at the last row in the table, and uses the larger of these two values.

When the table is empty, the largest actual rowid is instead assumed to be zero. This is done so that the first inserted rowid becomes 1.

Therefore, the only way to generate a rowid less than one is to have another row already in the table.




回答2:


I was using sqlite in java and unintentionally go the first row to have ROWID=0.

Here is the code

    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);

The intent was to have zero be an uninitialized value but insert was returning zero. I didn't want the first ROWID to equal zero so I removed the line and insert returned one.



来源:https://stackoverflow.com/questions/35043256/sqlite-starting-rowid-of-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!