dnkoutso
dnkoutso

Reputation: 6061

Android content provider query IN clause

Is possible to use an IN clause for a content provider?

I am currently using

cursor = contentResolver.query(CONTENT_URI, PROJECTION, "field IN (?)", new String[] { argsBuilder.toString() }, null);

If i remove the (?) and just use ? I get an error.

I get 0 count in my cursor.

If I type manually and execute the query in sqlite3 it works.

Help?

Upvotes: 12

Views: 5530

Answers (3)

Mike
Mike

Reputation: 1

This is a code snippet from my application built in Kotlin, the params array is for illustration purposes only as the parameters come from elsewhere in the code.

The problem with most of the proposed solutions is that they result in the loss of the SQL injection prevention that the use of placeholders provides, so I only use an expression that returns an array of "?" and whose quantity matches the array of provided parameters and then becomes a comma separated String.

That way, the delivered string is a string of placeholders and not the parameters directly.

Sorry for my first answer write in spanish.

var params = arrayOf("1789","1787","1694","1784")
applicationContext.contentResolver.query(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    null,
   "_ID IN (" +  Array(params.size) { "?" }.joinToString() + ")",
    params,
    null
)

Upvotes: 0

Femi
Femi

Reputation: 64710

When using the IN operator, you need to have one ? separated by a comma per argument you provide in your selectionArgs array. E.g.:

String[] selectionArgs = {"red", "black"};
String selection = "color IN (?, ?)";

The following picks the right count and the proper args:

int argcount = 2; // number of IN arguments
String[] args = new String[]{ 1, 2 };
StringBuilder inList = new StringBuilder(argcount * 2);
for (int i = 0; i < argcount; i++) { 
    if(i > 0) {
        inList.append(",");
    }
    inList.append("?"); 
}
cursor = contentResolver.query(
   CONTENT_URI, 
   PROJECTION, 
   "field IN (" + inList.toString() + ")", 
   args, 
   null);

Upvotes: 24

saschoar
saschoar

Reputation: 8230

If your arguments are numbers only, this works as well:

Iterable args = ...; // any array, list, set, ... 
cursor = contentResolver.query(CONTENT_URI, PROJECTION, "field IN (" + TextUtils.join(",", args) + ")", null, null);

Upvotes: 3

Related Questions