【问题标题】:Android rawquery with dynamic Where clause带有动态 Where 子句的 Android rawquery
【发布时间】:2014-01-23 04:51:31
【问题描述】:

我正在尝试在 Android 中执行这样的 SQL 查询:

SELECT * FROM Flashcards WHERE (category = 'Anatomy' OR category = 'Surgery') AND (difficulty = 'Easy' OR difficulty = 'Medium');

类别和难度的数量在运行时由用户选择确定。到目前为止,我已经尝试使用带有查询参数的原始查询,但我觉得在这种情况下我正在与框架作斗争:

String query = "SELECT * FROM Flashcards WHERE (?) AND (?) ORDER BY RANDOM() LIMIT 1";
    Cursor cursor = db.rawQuery(query, queryParameters);

我尝试传入的查询参数包括:

category = 'Anatomy' OR category = 'Surgery'

还有:

category = Anatomy OR category = Surgery

查询一直没有返回任何结果。在外部对同一个数据库执行的相同查询确实会返回结果。

【问题讨论】:

  • 需要指定列名 WHERE category= ?或类别 =?
  • 类别数=?条件将根据用户选择的类别数量而有所不同。
  • +1 来自我的“但我觉得在这种情况下我正在与框架作斗争”部分
  • 我认为你不使用简单查询。你想使用 rawquery.right?

标签: android sqlite


【解决方案1】:

试试:

String query = "SELECT * FROM Flashcards WHERE category = ? OR category = ? ORDER BY RANDOM() LIMIT 1";
Cursor cursor = db.rawQuery(query, queryParameters);

仅供参考,参数位置应该用 ?签名。

更新:

由于您想传递字段名称和值运行时间,您可以构建格式化字符串,例如:

String query = "SELECT * FROM Flashcards WHERE %s AND %s ORDER BY RANDOM() LIMIT 1";
Cursor cursor = db.rawQuery(String.format(query, queryParameters));

您必须使用 category = 'Anatomy' OR category = 'Surgery' 之类的东西来构建 queryParameters 值,正如您所提到的。

【讨论】:

  • 您好,感谢您的回答。我知道如何将 rawQuery 与查询参数一起使用。我不知道如何将 rawquery 与在运行时确定的多个 OR 条件一起使用。抱歉,我的问题是我的错(已编辑)。
  • 谢谢,这正是我所需要的。我现在就试一试。
【解决方案2】:

我一直发现原始查询的连接字符串容易出错且乏味。我最近发布了 Android 上 sqlite 操作的 fluent API 的初稿。有了它,您可以编写如下代码:

public void getFlashcards(SQLiteDatabase db, List<String> categories, List<String> difficulties) {
  Cursor c = select()
      .from("Flashcards")
      .where(column("category").in(nArgs(categories.size())), categories.toArray())
      .where(column("difficulty").in(nArgs(difficulties.size())), difficulties.toArray())
      .orderBy("RANDOM()")
      .limit(1)
      .perform(db);

  // do something useful with the cursor
}

private Expression[] nArgs(int size) {
  return Collections.nCopies(size, Expressions.arg()).toArray(new Expression[size]);
}

此代码将执行以下查询:

SELECT * FROM Flashcards WHERE (category IN (?, ?)) AND (difficulty IN (?, ?)) ORDER BY RANDOM() LIMIT 1;

? args 的数量取决于传递给函数的类别和难度集合的大小。另外,由于查询使用绑定参数而不是原始字符串,因此您的输入将被正确转义,并且此查询的准备语句对 SQLiteDatabase 内的缓存更友好。

API 仍然不完美,但 IMO 击败了基于 String.format() 的代码。试一试:android-db-commons

【讨论】:

    【解决方案3】:

    试试这个

    Select * from table_name where contains(fieldname,' "value1" OR "value2" OR "value3"')
    

    你拥有的其他一切看起来都很好。这在过去对我有用。根据需要添加任意数量的 OR

    好的'like和instep都被SQLite支持了

    SELECT *  FROM TABLE  WHERE instr(column,' "value1" OR "value2" OR "value3"'  );
    
    SELECT *  FROM TABLE  WHERE like(column,' "value1" OR "value2" OR "value3"') 
    

    另外,请记住 LIKE 不区分大小写,而 instr 区分大小写。

    【讨论】:

    • 我尝试使用 CONTAINS 但它似乎不是可识别的 SQLite 函数?
    • @Angavar 我认为你可以使用 Like tutorialspoint.com/sqlite/sqlite_like_clause.htm
    • 我不知道SQLite是否支持CONTAINS,但你可能对IN子句感兴趣。在Android中使用可能比较麻烦,希望this answer能有用。
    • 包含一个oracle平台函数。你没有指定。无论如何,您可以将包含替换为“喜欢”。要么。 “指示”。看看哪一种效果最好。
    • 好一个@andrew.. 我也建议喜欢或instr
    【解决方案4】:

    这是 android 的 SQLiteDatabase 类中的一个错误。

    似乎“category”是android SQLiteDatabase代码中的一个关键词,并且在android端的where子句中编写查询时不会返回任何内容。

    我也遇到了这个问题,将我的列名从 "category" 更改为其他名称解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-05
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      相关资源
      最近更新 更多