27

I want to delete rows which satisfy any of multiple conditions.

For example, I pass a list of IDs, and I want to delete all rows with these IDs (IDs are unique).

This would be:

String[] ids = {"0", "1", "2", "3",...};
database.delete("rows" , "id=? OR id=? OR id=? OR id=? OR ..." , ids );

Is there any way to do it compact without multiple OR?

2
  • SQL, you can use DISTINCT. Commented Jan 16, 2013 at 12:01
  • 1
    use DELETE FROM your_table_name WHERE ID IN (ids[0], ids[1],...) Commented Jan 16, 2013 at 12:04

7 Answers 7

64

You may get it done through db.execSQL method and SQL's IN keyword. For example:

String args = TextUtils.join(", ", ids);

db.execSQL(String.format("DELETE FROM rows WHERE ids IN (%s);", args));
Sign up to request clarification or add additional context in comments.

6 Comments

One way to do it is: for(int i = 0; i < ids.sixe(); ++i) { database.delete("rows", "id=" + ids.get(i), null); } I want to know if I can do that but in compact formar, with only one sentence "delete"
you can do that too but in that case it will execute sql statements a couple of times and has performance impact. Instead, I would suggest you to use IN statement to execute your query in bulk.
This is nice and short but it's not using parameter binding, which is a security concern. What if there happens to be an id like 1) OR (1=1 ...
TextUtil.join didn't know about it before ! pretty handy
Pēteris Caune, I believe you are correct. The command should be ... WHERE ids IN (?) and then args should be passed as the second argument to execSQL()
|
18

What you want to use is an IN clause, something like (with 4 IDs);

database.delete("rows", "id IN (?, ?, ?, ?)", ids );

Upon request, this is (one example of) how you can do it dynamically;

database.delete("rows", 
    "id IN (" + new String(new char[ids.length-1]).replace("\0", "?,") + "?)", 
    ids);

4 Comments

But the problem is that I have multiple IDs in the "ids" array, maybe 4 or maybe 1000 IDs.
One way to do it is: for(int i = 0; i < ids.sixe(); ++i) { database.delete("rows", "id=" + ids.get(i), null); } I want to know if I can do that but in compact formar, with only one sentence "delete".
@alberking Added a dynamic version.
@waqaslam Why do you say so? As, I just tested this code - gist.github.com/yccheok/ae18957e2715173adb50b426a1ef455d It works fine for me.
7

Android official documentation tells here that using execSQL is not the proper way to delete records.

I would like to suggest the following simple method. Using provided delete() api.

String[] idArray = new String[] {"1", "2", "3"};
String idsCSV = TextUtils.join(",", idArray);
SQLiteDatabase db = getWritableDatabase();
if (db != null) {
    db.delete("table_name", "id IN (" + idsCSV + ")", null);
    db.close();
}

Comments

2

You could use id IN (1, 2, 3, 4, ...) and directly print your array values inside the brackets:

database.delete("rows", String.format("id IN (%s)", StringUtils.join(ids, ",")));

As an alternative, I'd try to use some kind of flags column for such things (if there's something like being able to flag single entries for deletion; I don't know how your ID list is "built").

5 Comments

One way to do it is: for(int i = 0; i < ids.sixe(); ++i) { database.delete("rows", "id=" + ids.get(i), null); } I want to know if I can do that but in compact formar, with only one sentence "delete"
If you're not working with an array, you could just use a loop like yours concatenating a string with all ids (essentially the same as the result from StringUtils.join().
In order to satisfy the 3 args needed for delete(), you'll need to add new String [] {}.
Same as for waqaslam's answer, splicing parameters into SQL query is not a good practice. It is OK in some cases but generally should be avoided
@PēterisCaune Well, you have to assume they're safe already. Of course you shouldn't just throw in whatever you've got from a query.
0

Here's an example which builds the "?, ?, ?, ..." placeholder string with StringBuilder. If there are many parameters, plain string concatenation would create lots of garbage, StringBuilder helps with that.

String[] ids = {"0", "1", "2", "3",...};

StringBuilder placeholders = new StringBuilder();
for (int i = 0; i < ids.length; i++) {
    if (i != 0)
        placeholders.append(", ");

    placeholders.append("?");
}

String where = "id IN (" + placeholders.toString() + ")";

db.delete("rows", where, args);

Comments

0

I have done this using this :

Sqlite Statement Syntax :

db.delete(TABLE_NAME,"COLUMN IN (?)", new String[]{commaSaparatedString})

Example based on question :

String args = TextUtils.join(", ", ids);
db.delete("rows","id IN (?)", new String[]{args})

2 Comments

This did not work for me, db.delete returned 0 = no rows got deleted.
here is the reason why it doesn't work and how to do this right stackoverflow.com/a/26230484/4528239
0

This work for my varchar ID.

public Integer deleteObjects(List<Object> objects){
    if (objects.size()<1) return 0;
    SQLiteDatabase db = getWritableDatabase();
    StringBuilder strb= new StringBuilder();
    for(int i = 0; i<objects.size();i++){
        strb.append("'");
        strb.append(objects.get(i).getId().toString());
        strb.append("'");
        // last element without comma
        if (i<objects.size()-1) strb.append(","); 
    }
    int rows = db.delete("table_name","id IN (" + strb + ")",null);
    db.close();
    return rows;
}

This build WHERE string with args directly. Equivalent to:

 db.delete(TABLE_NAME,"id IN ('id0-maddog','id1-foo','id2-bar')",null); 

👌

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.