我正在使用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完成此类查询的任何建议?
答案 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(...)
方法的参数数量相匹配准确。