在Android / SQLite中获取未使用的rowid的有效方法?

时间:2013-02-22 16:20:04

标签: android sqlite

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

为此您定义:

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

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

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

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

但是,执行此任务的最有效方法是什么?

注意: 我不想在myTable中创建行。 但是当然你可以创建行并删除它 如果那是最好的工作方式。

5 个答案:

答案 0 :(得分:1)

您可以从sqlite_sequence table

中读取该序列的当前值

答案 1 :(得分:1)

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

SELECT id FROM myTable ORDER BY id DESC

然后查看返回的第一行的id并将其递增1。但请注意并发性。如果在检查未使用的行之后立即插入某些内容,则可能会出现意外行为。

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

答案 2 :(得分:0)

我永远不明白为什么有人会这样做,但可以做到:

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

This S.O. answer解释了查询sqlite_sequence表以查找当前最大ID的一种方法,然后可以向其添加1,并且99.9%的时间这将是下一个发布的ID。

答案 3 :(得分: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,其他任何人都无法获得。 也许这些陈述必须在同一笔交易中。

对于简单而常见的任务来说,这不是那么简单吗?

答案 4 :(得分: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;
}