I'm trying to create a Cursor
from a table, constrained to a certain set of ID's, passed into the selection
arguments as follows: (simplified for readability)
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);
The idea is that this Cursor
will be filled with any item whose id matches an item in the list.
This works ok, except for a huge list, I get an SQLiteException
, as the argument is too large:
android.database.sqlite.SQLiteException: Expression tree is too large (maximum depth 1000)
I understand why this is happening. The query is built as:
selection = Table.column._ID = id[1] OR Table.column._ID = id[2] ...
And can get pretty massive.
The question is, how can I make this query work? Surely there is a more efficient way to populate a Cursor
with a huge list of constraints / selection criteria, right?
Should I be passing the ids into selectionArgs
and dealing with it that way?
Thanks to pskink for his input. The answer is to use the 'IN' operator.
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(")");
This is the equivalent of:
Selection = "Table.column._ID IN (ids[1], ids[2], ids[3], ...);
Which is much better than:
Selection = "Table.column._ID = ids[1] OR Table.column._ID = ids[2] OR Table.column._ID = ids[3] ...";