2

我正在使用 QueryBuilder 构建内部 SQL,稍后在原始 SQL 中使用该内部 SQL,以避免手动转义无效字符。

SelectArg friendsIN = new SelectArg(friendsUsernames);
QueryBuilder<MyObject, Integer> qb = myObjectDao.queryBuilder();
qb.selectRaw("username", "MAX(time) AS latestTime").groupBy("username").where()
    .in("username", friendsIN);
String innerSelect = pq.getStatement();

friendsUsernames定义为ArrayList<String>

然后我使用innerSelect来构建外部选择:

String select = "SELECT w.id FROM (" + innerSelect +") AS x INNER JOIN myObject AS w on w.username = x.username AND w.time = x.latestTime";
GenericRawResults<String[]> results = myObjectDao.queryRaw(select);

但是,正如预期的那样,innerString'?'我打电话时queryRawmyObjectDao我没有得到任何结果。我试图将friendsUsername 作为数组提供给queryRaw:

GenericRawResults<String[]> results =
    myObjectrDao.queryRaw(select,
         friendsUsernames.toArray(new String[friendsUsernames.size()]));

但我收到以下错误:

android.database.sqlite.SQLiteBindOrColumnIndexOutOfRangeException:
      bind or column index out of range: handle 0x17a22e8

有关如何使用 OrmLite 完成此类查询的任何建议?

4

1 回答 1

4

是的,那是行不通的。您的查询中只有一个?,但您正在尝试传入一组用户名。?SQL 参数的数量和传递给方法的参数数量之间必须存在一一对应的关系queryRaw(...)

如果friendsUsernames是固定大小,那么您应该能够执行以下操作,这将生成类似于以下内容的 SQL "in (?, ?, ?, ?)"

List<SelectArg> friendsInList = new ArrayList<SelectArg>();
for (int i = 0; i < NUM_FRIENDS; i++) {
   // it doesn't matter what the value is since you just want the ?
   fieldsInList.add(new SelectArg());
}
...in("name", friendsInList);

但是,如果名称列表是动态的,那么您将不得不即时执行此操作,因为再次,数量?必须与传递给queryRaw(...)方法的参数数量完全匹配。

于 2012-08-29T12:38:30.707 回答