1

假设您不想为下面的表 myTable 回收 rowid。

为此,您定义:

CREATE TABLE myTable
(
  id INTEGER PRIMARY KEY AUTOINCREMENT ,
  <Other columns>
)

然后你想在 android/SQLite 环境中获取下一个未使用的 rowid。

你将如何有效地做到这一点?

也许我们需要对象 android.database.sqlite.SQLiteDatabase 和也许(?)对象 android.database.sqlite.SQLiteStatement

但是完成这项任务的最有效方法是什么?

注意:我不想在 myTable 中创建行。但当然,如果这是完成这项工作的最佳方式,您可以创建行并将其删除。

4

5 回答 5

1

您可以从sqlite_sequence 表中读取该序列的当前值。

于 2013-02-22T16:23:29.487 回答
1

正如您所确定的,创建一行并删除它是一种有效的方法。另一种方法是运行

SELECT id FROM myTable ORDER BY id DESC

然后查看返回的第一行的 id 并将其加一。不过要小心并发。如果在检查未使用的行后立即插入某些内容,则可能会出现一些意外行为。

编辑:查看 CL. 的答案。它更实用。另外,您可以手动更新增加该表的序列号,以保证您的行不会被使用。

于 2013-02-22T16:24:57.263 回答
0

SQLiteOpenHelper你使用的内部,开始一个事务。插入一些数据,然后回滚。

这样,您将能够获得下一行 id,如下所示:

public long nextId() {
    long rowId = -1;

    SQLiteDatabase db = getWritableDatabase();
    db.beginTransaction();
    try {
        ContentValues values = new ContentValues();
        // fill values ...

        // insert a valid row into your table
        rowId = db.insert(TABLE_NAME, null, values);

        // NOTE: we don't call  db.setTransactionSuccessful()
        // so as to rollback and cancel the last changes
    } finally {
        db.endTransaction();
    }
    return rowId;
}
于 2013-09-19T08:09:42.127 回答
0

所以答案是这样的:

db.execSQL("UPDATE sqlite_sequence set seq=seq+1 WHERE name='myTable'");

SQLiteStatement st = db.compileStatement("SELECT seq from sqlite_sequence WHERE name='myTable'");
long v = st.simpleQueryForLong();
st.close();

现在 v 是未使用的 rowid ,其他任何人都不会得到。也许这些语句必须在同一个事务中。

对于简单且相当常见的任务来说不是那么简单吗?

于 2013-02-22T17:30:05.113 回答
0

我从来不明白为什么有人需要这样做,但可以做到:

SQLite 文档提到 auto_increment 值存储在一个sqlite_sequence表中,当您使用 auto_increments 时,该表会在您的数据库中自动创建。

这个 SO 答案解释了一种查询sqlite_sequence表以查找当前最大 ID 的方法,然后您可以向它添加 1,并且 99.9% 的时间这将是下一个发布的 ID。

于 2013-02-22T16:32:20.863 回答