我的SQLite数据库中有一个表:

种类:

_id  |  species  |  description
---------------------------
  1  |  Aardvark |  Some description for Aardvark
  2  |  Aardwolf |  Some description for Aardwolf
  3  |  Caracal  |  Some description for Caracal


我从服务器收到ID列表,我只想显示与我收到的ID对应的种类。

现在我知道一些选择:

1.一种明显而幼稚的方式是:

SQLiteDatabase db = this.openDatabase();
for (int id : idList) {
    Cursor cursorSpecies = db.query(true, TABLE_SPECIES, new String[] {COL_SPECIES_SPECIES},
            COL_ID + "=?", id, null, null, null, null);
    cursorSpecies.moveToNext();
    speciesList.add(cursorSpecies.getString(0));
    cursorSpecies.close();
}


这将执行太多的操作,并且我假设读取多个小“磁盘”,这将非常慢。

2.另一个选择是使用SQLiteStatement,但这仅返回一个值,无论如何对于我的示例和shouldn't really be used for queries都无效。

3.另一个选择是将条件手动连接到原始的SQL查询中,大致类似于:

SQLiteDatabase db = this.openDatabase();
String query = "SELECT * FROM " + TABLE_SPECIES + " WHERE ";
for (int id : idList) {
    query += COL_ID + "=" + id + " OR ";
}
// I am aware this will end in an " OR" but this is not the point of this example so please ignore it.
Cursor cursorSpecies  = db.rawQuery(query, null);
// Use the cursor and close it.

While this should work decently well, a very large query would probably break some query string length limit so this is not ideal either.


所有这些示例都可以在一定程度上起作用,但是它们都有陷阱。不知何故,我觉得我缺少解决方案,因此提出了一个问题:

执行这类查询的正确方法是什么?

谢谢。

最佳答案

对于问题中的特殊情况,仅考虑WHERE id IN (x,y,z, ...)

要在标题中解决问题,而不仅仅是问题正文中的特殊情况:

在这方面,Android SQLite API并不是很通用。

在原始sqlite3 C API中,可以通过单个sqlite3_prepare*()调用来获得sqlite3_statement并将其绑定到位,使用sqlite3_step()来获取行,然后重置该语句以将其与新的参数绑定一起重用。

在Android API中,该语句对应于Cursor,而步进等效于移动光标。重置和重新绑定功能仅在SQLiteCursor中以requery()setSelectionArguments()的形式提供。

因此,请尝试以下方法:


使用选择参数进行常规查询。
假定默认光标工厂,将结果Cursor强制转换为SQLiteCursor
访问您需要的行。
setSelectionArgs()更新选择参数
requery()
转到3,除非完成

07-25 23:58
查看更多