OrmLite使用SelectArg在select中选择以转义字符

时间:2012-08-29 07:10:13

标签: android ormlite

我正在使用QueryBuilder来构造内部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'?',当我在queryRaw上致电myObjectDao时,我没有得到任何结果。我试图将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完成此类查询的任何建议?

1 个答案:

答案 0 :(得分:4)

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

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

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(...)方法的参数数量相匹配准确。