Android: SQLite - правильный способ создания курсора с большим массивом ограничений выбора
Я пытаюсь создать Cursor
из таблицы, ограниченной определенным набором идентификаторов, переданных в selection
аргументы следующие: (упрощено для удобства чтения)
String[] ids; //The id's to constrain the cursor to
StringBuilder selection;
//for each id, add to the selection
for(int i = 0; i < ids.length(); i++) {
selection = Table.column._ID + " = " + ids[i];
if(i < ids.length -1) {
selection.append( "OR" ) //Add an "OR" after each selection (except the last)
}
}
Cursor cursor = query(uri, projection, selection.toString(), null, null);
Идея в том, что это Cursor
будет заполнен любым элементом, чей идентификатор соответствует элементу в списке.
Это работает нормально, за исключением огромного списка, я получаю SQLiteException
, поскольку аргумент слишком велик:
android.database.sqlite.SQLiteException: Expression tree is too large (maximum depth 1000)
Я понимаю, почему это происходит. Запрос построен как:
selection = Table.column._ID = id[1] OR Table.column._ID = id[2] ...
И может стать довольно массивным.
Вопрос в том, как я могу заставить этот запрос работать? Конечно, есть более эффективный способ заполнить Cursor
с огромным списком ограничений / критериев выбора, верно?
Должен ли я передавать идентификаторы в selectionArgs
и справляться с этим таким образом?
1 ответ
Спасибо pskink за его вклад. Ответ заключается в использовании оператора "IN".
String[] ids; //The id's to constrain the cursor to
StringBuilder selection;
selection = Table.column._ID + " IN (";
for(int i = 0; i < ids.length(); i++) {
selection.append(ids[i]);
if(i < ids.length -1) {
selection.append( "," ) //Add an "," after each selection (except the last)
}
}
selection.append(")");
Это эквивалент:
Selection = "Table.column._ID IN (ids[1], ids[2], ids[3], ...);
Что намного лучше чем:
Selection = "Table.column._ID = ids[1] OR Table.column._ID = ids[2] OR Table.column._ID = ids[3] ...";