我想从CalendarProvider API查询日历。在我的应用程序的设置中,用户可以检查并取消选中他想在我的应用程序中使用哪些日历。我使用的表USEDCALENDARS
得到了_id(int),calendar_id(int)和used(int)列。
现在我想展示一个Spinner,其中包含用户选择的每个可写日历。我的方法是:从USEDCALENDARS收集所有calendar_ids,其中used = 1(true)。然后使用收集的id作为queryparam查询CalendarProvider。请在这里查看我的代码。
//using a simple list as calendarIds because the code that collects the id is working perfectly
List<Long> calendarIds = Arrays.asList(1L,2L,3L);
String selection = Calendars._ID + " IN (?)";
String joinedCalendarIds = StringUtils.join(calendarIds, ", ");
String[] selectionArgs = new String[]{
joinedCalendarIds
};
return cr.query(Calendars.CONTENT_URI, GOOGLE_CALENDARS_PROJECTION, selection,selectionArgs, Calendars.CALENDAR_DISPLAY_NAME);
这是返回一个空光标。但是如果你用代码的第一行交换。 List<Long> calendarIds = Arrays.asList(1L);
(基本上将ID数量限制为1),将返回正确的日历。
我走向错误的方向吗?为什么这不起作用?有更好的方法吗?
答案 0 :(得分:1)
我认为问题在于如何解析paramneterised IN 子句。
我按照以下代码做了一些测试(4): -
String[] selectionargs = {"1","2","3"};
String[] oldselectionargs = {"1,2,3"};
SQLiteDatabase db = mydbhelper.getWritableDatabase();
String oldselection = "_id IN(?)";
String selection = "_id" + " IN (";
String selection4 = "_id IN (";
for (int i=0; i < selectionargs.length; i++) {
if (i > 0) {
selection = selection + ", ";
}
selection = selection + selectionargs[i];
}
selection = selection + ")";
String[] columns = {mydbhelper.MYFLOATCOL};
Cursor cursor = db.query(mydbhelper.TESTFLOATTABLE,columns,selection,null,null,null,null);
Log.d("DBIN","Cursor Count=" + cursor.getCount());
while (cursor.moveToNext()) {
Log.d("DBIN",cursor.getString(cursor.getColumnIndex(mydbhelper.MYFLOATCOL)));
}
Cursor cursor2 = db.query(mydbhelper.TESTFLOATTABLE,columns,oldselection,oldselectionargs,null,null,null);
Log.d("DBIN","Cursor Count=" + cursor2.getCount());
while (cursor2.moveToNext()) {
Log.d("DBIN",cursor2.getString(cursor2.getColumnIndex(mydbhelper.MYFLOATCOL)));
}
Cursor cursor3 = db.query(mydbhelper.TESTFLOATTABLE,columns,
"_id IN (" + oldselectionargs[0].toString() + ")",null,null,null,null);
Log.d("DBIN","Cursor Count=" + cursor3.getCount());
while (cursor3.moveToNext()) {
Log.d("DBIN",cursor3.getString(cursor3.getColumnIndex(mydbhelper.MYFLOATCOL)));
}
for (int i=0; i < selectionargs.length; i++) {
if (i > 0) {
selection4 = selection4 + ",";
}
selection4 = selection4 + "?";
}
selection4 = selection4 + ")";
Cursor cursor4 = db.query(mydbhelper.TESTFLOATTABLE,columns,selection4,selectionargs,null,null,null);
Log.d("DBIN","Cursor Count=" + cursor4.getCount());
while (cursor4.moveToNext()) {
Log.d("DBIN",cursor4.getString(cursor4.getColumnIndex(mydbhelper.MYFLOATCOL)));
}
cursor.close();
cursor2.close();
cursor3.close();
cursor4.close();
以上代码的输出: -
07-14 13:55:54.717 23634-23634/? D/DBIN: Cursor Count=3
07-14 13:55:54.717 23634-23634/? D/DBIN: 100
07-14 13:55:54.717 23634-23634/? D/DBIN: 200
07-14 13:55:54.717 23634-23634/? D/DBIN: 300
07-14 13:55:54.718 23634-23634/? D/DBIN: Cursor Count=0
07-14 13:55:54.720 23634-23634/? D/DBIN: Cursor Count=3
07-14 13:55:54.720 23634-23634/? D/DBIN: 100
07-14 13:55:54.720 23634-23634/? D/DBIN: 200
07-14 13:55:54.720 23634-23634/? D/DBIN: 300
07-14 13:55:54.721 23634-23634/? D/DBIN: Cursor Count=3
07-14 13:55:54.721 23634-23634/? D/DBIN: 100
07-14 13:55:54.721 23634-23634/? D/DBIN: 200
07-14 13:55:54.721 23634-23634/? D/DBIN: 300
因此第1,第3和第4种方法起作用(即光标,cursor3和cursor4返回预期值),第2次传递“1,2,3”作为参数不起作用(即你尝试的方式)。
第一个,使用cursor1,使用一个值数组并构建一个逗号
包含在选择中的分隔字符串
selectionargs
为null。
第二个,使用cursor2,基本上是什么 你试过
第3只使用硬编码字符串,即真的没有 与第1次不同
第4个构建WHERE(IN)子句,其中包含要传递的适当数量的参数,例如.... IN (?,?,?)
并使用最初定义的selectionargs
数组。