使用ID删除多行?
问题描述:
如何通过Android SQLite数据库中的ID列表删除多行?使用ID删除多行?
我已经以这种方式定义的一般删除方法:
protected void deleteWhere(String whereClause, String[] whereArgs) {
try {
databaseHelper.getWritableDatabase().delete(
getTableName(), whereClause, whereArgs);
} finally {
databaseHelper.close();
}
}
现在我想用ID列表来调用它:如果ID列表包含
public void deleteAll(Iterable<T> entities) {
Iterable<Long> ids = Iterables.transform(entities, getId);
String whereClause = getIdColumn() + " IN (?)";
String[] whereArgs = { TextUtils.join(",", ids) };
deleteWhere(whereClause, whereArgs);
}
例如值[1,2,42],那么我假设生成的SQL应该是:
DELETE FROM tableName WHERE _id IN (1,2,42);
但是,这似乎不工作co rrectly。如果列表仅包含1个ID,则它被正确删除。但是,如果我提供多个值,则会影响零行。我究竟做错了什么?
答
当你给一个字符串作为whereArgs
,一个字符串中的SQL命令结束了,因为如果你写了这个:
... WHERE _id IN ('1,2,42')
这将比较每个_id
的值与值'1,2,42'
,这当然不起作用。
如果使用三个参数标记和whereArgs
数组中给三根弦,你最终会用三根弦,像这样:
... WHERE _id in ('1','2','42')
这只能当_id
列具有integer affinity,这是对于声明为INTEGER PRIMARY KEY的列为true,但在一般情况下不适用。
Android数据库API不允许查询参数具有任何类型但字符串。 当使用整数时,你应该直接插入(在ianhanniballake's answer):
String whereClause = getIdColumn() + " IN (" + TextUtils.join(",", ids) + ")";
答
不能使用whereArgs
为IN
语句因逃逸通过whereArgs
(除非你做每个值单独?
) - 相反,你必须嵌入IDS在这里声明:
String whereClause = getIdColumn() + " IN (" + TextUtils.join(",", ids) + ")";
deleteWhere(whereClause, null);
哦,现在当我看到撇号被添加到值的方式时,这是有道理的。但是,是不是将值直接放入'whereClause'倾向于SQL注入?用适当数量的问号手动生成'whereClause'并将ID作为String数组传递给'whereArgs'不是更好吗? – Natix 2014-10-07 08:38:31
仅允许字符串作为参数是Android数据库API设计中的一个错误。无论如何,整数值对SQL注入是安全的;此问题仅出现在字符串中。 – 2014-10-07 08:40:36