游标如何引用已删除的行?

时间:2011-09-09 22:00:23

标签: android sqlite

当我从Android中的sqlite数据库查询中获取Cursor时,它似乎包含固定数量的行,无论数据库发生什么,这些行都不会更改。例如,如果在Cursor打开时删除了某些行,我仍然可以引用已删除的行。这很好,但它是如何工作的?

一个猜测可能是sqlite知道我有一个指向该行的Cursor,因此保留旧数据的副本。但是,如果我有一百万行,删除它们并用一百万个不同的行替换它们,看起来像要缓存的大量数据呢!

更新

我现在认为我们在Android中看到的这种缓存并不是真正的防弹,也不是SQLite的一部分。我创建了一个测试,它构建了一个包含1,000,000行的数据库,然后我查询了db打印出一些结果并将光标打开,接下来我删除了一半行,最后我试图访问我打开的光标和结果是一场崩溃:

04-05 18:17:16.141 E/AndroidRuntime(19655): java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.CursorWindow.nativeGetLong(Native Method)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.CursorWindow.getLong(CursorWindow.java:507)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:220)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
04-05 18:17:16.141 E/AndroidRuntime(19655):     at com.jacob.DirectDbActivity$4.run(DirectDbActivity.java:88)

这似乎是Android中的一个错误,因为大多数数据库都很小,缓存窗口可以容纳所有结果,但在大型数据库中,这将会打击你。

1 个答案:

答案 0 :(得分:2)

最后我检查过,游标是基于创建它的SQL的数据库快照。很像数据集。如果更改数据库,游标可能不知道它们的快照是旧的。您可以对游标执行重新查询,以根据创建游标的原始SQL获取新数据。