【问题标题】:How to delete rows in SQLite with multiple where args?如何删除 SQLite 中具有多个 where 参数的行?
【发布时间】:2012-12-30 17:53:44
【问题描述】:

我想删除满足多个条件中的任何一个的行。

例如,我传递了一个 ID 列表,我想删除所有具有这些 IDs 的行(ID 是唯一的)。

这将是:

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

有没有办法在没有多个OR的情况下做到紧凑?

【问题讨论】:

  • SQL,可以使用DISTINCT。
  • 使用 DELETE FROM your_table_name WHERE ID IN (ids[0], ids[1],...)

标签: android database sqlite


【解决方案1】:

您可以通过db.execSQL 方法和SQL 的IN 关键字来完成。例如:

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

db.execSQL(String.format("DELETE FROM rows WHERE ids IN (%s);", args));

【讨论】:

  • 一种方法是:for(int i = 0; i
  • 您也可以这样做,但在这种情况下,它会执行几次 sql 语句并影响性能。相反,我建议您使用 IN 语句批量执行查询。
  • 这很好很简短,但它没有使用参数绑定,这是一个安全问题。如果碰巧有一个像1) OR (1=1这样的id怎么办...
  • TextUtil.join 以前不知道!很方便
  • Pēteris Caune,我相信你是对的。命令应该是 ... WHERE ids IN (?) 然后 args 应该作为第二个参数传递给 execSQL()
【解决方案2】:

您可以使用id IN (1, 2, 3, 4, ...) 并在括号内直接打印您的数组值:

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

作为替代方案,我会尝试使用某种flags 列来处理此类事情(如果能够标记单个条目以进行删除;我不知道您的 ID 列表是如何“构建”的)。

【讨论】:

  • 一种方法是:for(int i = 0; i
  • 如果您不使用数组,则可以使用像您这样的循环将字符串与所有 id 连接起来(与 StringUtils.join() 的结果基本相同。
  • 为了满足 delete() 所需的 3 个参数,您需要添加 new String [] {}
  • 与 waqaslam 的回答相同,将参数拼接到 SQL 查询中并不是一个好习惯。在某些情况下可以,但通常应该避免
  • @PēterisCaune 好吧,你必须假设它们已经安全了。当然,您不应该只输入从查询中得到的任何信息。
【解决方案3】:

您要使用的是 IN 子句,类似于(带有 4 个 ID);

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

根据要求,这是您如何动态执行此操作的(一个示例);

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

【讨论】:

  • 但问题是我在“ids”数组中有多个 ID,可能是 4 个,也可能是 1000 个 ID。
  • 一种方法是:for(int i = 0; i
  • @alberking 添加了动态版本。
  • @waqaslam 你为什么这么说?因为,我刚刚测试了这段代码 - gist.github.com/yccheok/ae18957e2715173adb50b426a1ef455d 它对我来说很好。
【解决方案4】:

这是一个使用 StringBuilder 构建“?, ?, ?, ...”占位符字符串的示例。如果有很多参数,纯字符串连接会产生很多垃圾,StringBuilder 可以帮助解决这个问题。

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);

【讨论】:

    【解决方案5】:

    我已经用这个做到了:

    Sqlite 语句语法:

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

    基于问题的示例:

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

    【讨论】:

    【解决方案6】:

    Android 官方文档告诉here 使用 execSQL 不是删除记录的正确方法。

    我想建议以下简单的方法。使用提供的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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-03
      • 2010-12-07
      • 2013-12-12
      • 2016-11-09
      • 2019-10-24
      相关资源
      最近更新 更多