【问题标题】:SQLite in operator in query()查询()中的 SQLite in 运算符
【发布时间】:2013-04-30 08:30:40
【问题描述】:

我这样调用 SQLite

String[] args = new String[]{"(A,B)"}
Cursor cur = db.query("tab1", null, "name in ?", args, null, null, null);

并收到异常:

android.database.sqlite.SQLiteException: near "?": syntax error: , while compiling: SELECT * FROM tab1 WHERE name in ?

如何在query()中使用in操作符?

我已经试过了

String[] args = new String[]{"('A','B')"}

【问题讨论】:

标签: android sqlite


【解决方案1】:
String[] args = new String[]{A,B} // if A, B are variables
String[] args = new String[]{"A","B"}    
Cursor cur = db.query("tab1", null, "name in (?,?)", args, null, null, null);  

【讨论】:

  • 当变量来自动态列表时如何清理?
【解决方案2】:

在处理一个项目并为同样的问题苦苦挣扎时,我发现这些其他问题(和答案)很有帮助:

  1. Sqlite Query for multiple values in one columm
  2. Android/SQLite IN clause and placeholders

这是我发现的作品:

String[] args = new String[] {"A", "B"};
Cursor cur = db.query("tab1", null, "name in(?,?)", args, null, null, null);

如愿以偿:

String args = "A, B";
Cursor cur = db.query("tab1", null, "name in(" + args + ")", null, null, null, null);



因此,您可以将多个?IN() 语句一起使用,并将每个与selectionArgs 数组中的一个元素匹配(如第一个示例)。如果您的WHERE 子句中有多个条件,请确保将?selectionArgs 中的正确元素匹配:

String[] args = new String[] {"Current", "A", "B"};
Cursor cur = db.query("tab1", null, "IsCurrent=? AND name in(?,?)", args, null, null, null);


或者,您可以直接在 selection 字符串本身的 IN() 语句中使用由逗号分隔的参数组成的字符串(如第二个示例)。



引用的问题似乎表明您可以在 IN() 中使用单个 ? 并以某种方式扩展相关参数,但我无法让它工作。

【讨论】:

  • 永远不要从字符串构造任何 sql 部分。它容易受到sql注入。
  • @PeterMmm 我对 sql 注入的话题一无所知(除了始终使用参数化 SQL 调用的规则),所以即使所有数据都来自应用程序内部,仍然有可能来自查询的注入攻击? ...或者如果将查询字符串发送到应用程序外部的 SQLite 数据库,查询字符串是否会损坏?
  • 重点是,所有请求(应该)通过相同的方法(在这种情况下为 query())。如果 query() 易受攻击并已修复,它将不再(或更少)易受攻击。
  • 您的观点“如果所有数据都来自应用程序内”,当开发人员发现“upss,有人可能会在这里注入不受控制的数据”时,他们给了他们很大的惊喜。我们很聪明,但黑客更聪明,
  • 确实如此。由于 SQL 注入漏洞,应使用字符串连接的方法。正如 Python 的 psycopg2 文档通常所说:“永远,永远,永远不要使用字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。甚至在枪口下也不行。” 这在 Android 和 SQLite 上也是如此。正确的方法是第一个,即String[] args = new String[] {"A", "B"}; Cursor cur = db.query("tab1", null, "name in(?,?)", args, null, null, null);,它使用了 selection 和 selectionArgs 参数
【解决方案3】:

如果我没记错的话,arg 解析不适​​用于 IN 子句。所以你不能使用'?在你的 WHERE 子句中。

你应该这样做:

String args = "A, B";
Cursor cur = db.query("tab1", null, "name in (" + args + ")", null, null, null, null);

如果需要,用循环构造你的参数。

【讨论】:

  • 这很容易受到 SQL 注入的攻击。请参阅stackoverflow.com/questions/16295432/… 如果您有很多元素,您可以使用其中的占位符以编程方式构造选择,并将值作为 selectionArgs 参数传递。在任何情况下,您都不应该使用字符串连接或格式化的值构建查询
【解决方案4】:

如果我理解正确,你可以这样解决你的问题:

List<String> exercise =  new ArrayList<>();
exercise.add(parameter1);
exercise.add(parameter2);
exercise.add(parameter3);

Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM exersisesenglish WHERE sex " + " 
=?" + " AND level" + "=?" + " AND wish" + "=?" + " AND place" + "=?" + " AND lang" + 
"=?" +" AND stay_exersise IN (" + exercise.get(0) + "," + exercise.get(1) + "," + 
exercise.get(2) + "," + exercise.get(3) + ")", new String[]{String.valueOf(sex), 
String.valueOf(level), String.valueOf(wish), String.valueOf(place), 
String.valueOf(loc)});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 2012-05-21
    • 2020-06-06
    • 1970-01-01
    • 2015-01-30
    • 2016-04-09
    相关资源
    最近更新 更多