假设您不想为下面的表myTable回收rowid。
为此您定义:
CREATE TABLE myTable
(
id INTEGER PRIMARY KEY AUTOINCREMENT ,
<Other columns>
)
然后你想在android / SQLite环境中获得下一个未使用的rowid。
你将如何有效地做到这一点?
也许我们需要对象 android.database.sqlite.SQLiteDatabase 也许(?)对象 android.database.sqlite.SQLiteStatement
但是,执行此任务的最有效方法是什么?
注意: 我不想在myTable中创建行。 但是当然你可以创建行并删除它 如果那是最好的工作方式。
答案 0 :(得分:1)
答案 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;
}