在 Android 2.2 上使用 FTS3 时 SQLite 的 RowId 不正确
我在使用 sqlite 和 fts3 时遇到不正确的 rowid 值。
基本上,插入前两行,rowId为1和2 分别。然而,第三次插入返回 4 而不是 3。
当我在我的 contentprovider 中删除了以下日志消息时 插入一行:
SQLiteDatabase database =
databaseHelper.getWritableDatabase();
long rowId = database.insert(NOTES_TABLE, Note.NOTE, values);
Log.d("NoteProvider", "RowId inserted was " + rowId);
该日志消息的输出是:
02-21 21:10:12.773: DEBUG/NoteProvider(2486): RowId inserted was 1
02-21 21:10:20.623: DEBUG/NoteProvider(2486): RowId inserted was 2
02-21 21:10:25.883: DEBUG/NoteProvider(2486): RowId inserted was 4
那么 3 发生了什么?
另外,我导出了 sqlite 数据库,这样我就可以在 SqLite 中查看 浏览器中,内容表显示 1、2 和 3。
因此创建了 3,但返回了 4。
我进行了最多 10 次测试,之后 rowId 是连续的, 但仍然落后 1。
数据库创建脚本是:
database.execSQL("CREATE VIRTUAL TABLE " + NOTES_TABLE + "
USING fts3 ("
+ Note.TITLE + ", "
+ Note.NOTE + ", "
+ Note.CREATED_DATE + ", "
+ Note.MODIFIED_DATE + ");");
我假设我做了一些严重错误的事情,但无法弄清楚 知道它是什么。 有人可以帮我吗?
编辑1:
做了更多测试,在 2.3.1 和 2.1 上得到了相同的结果。
虽然在2.1中id为1、3(跳过2)
编辑2:
终于想出了一个解决办法。不过我认为这是一个非常严重的错误或其他问题。 我最终做的是从表中选择最大 rowid,增加 1,然后将该值设置为插入时的 rowid。这是一个完整的解决方案。这是一个非常肮脏和廉价的黑客,但这是我唯一可以可靠地工作的东西。无论如何,这是代码:
SQLiteDatabase database = databaseHelper.getWritableDatabase();
SQLiteStatement statement = database.compileStatement("select ifnull(max(rowid), 0) as rowid from " + NOTES_TABLE);
long maxRowId = statement.simpleQueryForLong();
Log.d("NoteProvider", "Statement returned " + maxRowId);
long rowId = maxRowId + 1;
values.put("rowid", rowId);
database.insert(NOTES_TABLE, null, values);
Log.d("NoteProvider", "RowId inserted was " + rowId);
编辑 3:
看起来另一个人曾经/正在遇到这个问题。 Android 全文搜索和 ListAdapter
I am experiencing an incorrect rowid value with sqlite and fts3.
Basically, the first two rows are inserted and the rowId is 1 and 2
respectively. The third insert however returns 4 instead of 3.
I dropped the following log message in my contentprovider when
inserting a row:
SQLiteDatabase database =
databaseHelper.getWritableDatabase();
long rowId = database.insert(NOTES_TABLE, Note.NOTE, values);
Log.d("NoteProvider", "RowId inserted was " + rowId);
The output of that log message is:
02-21 21:10:12.773: DEBUG/NoteProvider(2486): RowId inserted was 1
02-21 21:10:20.623: DEBUG/NoteProvider(2486): RowId inserted was 2
02-21 21:10:25.883: DEBUG/NoteProvider(2486): RowId inserted was 4
So what happened to 3?
Also, I exported the sqlite database so I could look at in a SqLite
browser and the content table shows 1, 2 and 3.
So 3 was created but 4 was returned.
I ran my testing up to 10, and the rowId was sequential afterwards,
but still off by 1.
The database create script is:
database.execSQL("CREATE VIRTUAL TABLE " + NOTES_TABLE + "
USING fts3 ("
+ Note.TITLE + ", "
+ Note.NOTE + ", "
+ Note.CREATED_DATE + ", "
+ Note.MODIFIED_DATE + ");");
I am assuming I have done something horribly wrong, but cannot figure
out what it is.
Can anyone help me out?
Edit 1:
Did some more testing and have the same results on 2.3.1 and 2.1.
Although in 2.1 the ids when 1, 3 (skipped 2)
Edit 2:
Finally came up with a work around. However I think this is a pretty severe bug or something.
What I ended up doing was selecting the max rowid from the table bumping up by 1 and then setting that value to the rowid on insert. Its a complete suck solution. A very dirty and cheap hack, but it is the only thing I get to work reliably. Anyway here is the code:
SQLiteDatabase database = databaseHelper.getWritableDatabase();
SQLiteStatement statement = database.compileStatement("select ifnull(max(rowid), 0) as rowid from " + NOTES_TABLE);
long maxRowId = statement.simpleQueryForLong();
Log.d("NoteProvider", "Statement returned " + maxRowId);
long rowId = maxRowId + 1;
values.put("rowid", rowId);
database.insert(NOTES_TABLE, null, values);
Log.d("NoteProvider", "RowId inserted was " + rowId);
Edit 3:
Looks like another fellow was/is having this problem.
Android Full Text Search and ListAdapter
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我也遇到了同样的问题,并提出了与您类似的解决方案:)
但是,由于 我在使用 FTS3 时遇到的其他麻烦 我完全重新设计了数据库:将非文本列推送到单独的表,将文本字段推送到其他表并创建查询视图;以及删除的触发器。
因此现在我使用的是旧的
Table._ID
:)I ran into the same issue as well and came up with solution similar to yours :)
However, due to other troubles I had with FTS3 I have completely redesigned the database: pushed non text columns to separate table, text fields to other one and created view for query; as well as triggers for delete.
Therefore now I am using good old
Table._ID
:)这看起来是 SQLite 中的一个错误。原帖“编辑2”中的解决方案似乎工作正常。还没有在 Honeycomb 中尝试过以验证它是否已修复。
This looks to be a bug in SQLite. The solution in "Edit 2" of the original post seems to be working ok. Have not tried it out in Honeycomb to verify it has been fixed there.