Java 使用arraylist中的字符串值的Android-sqlite in子句?

Java 使用arraylist中的字符串值的Android-sqlite in子句?,java,android,sqlite,arraylist,android-sqlite,Java,Android,Sqlite,Arraylist,Android Sqlite,s1.ListViewCategory是Singleton类s1中的字符串类型ArrayList,它具有类别值:游戏、国家、城市、地铁、演员、宠物//在数据库中总共有33个类别,我想排除s1.ListViewCategory中的这6个类别 在rawQuery中,我想排除s1.ListViewCategory中的类别,因此我尝试了两种光标引用这两个stackoverflow问题的方法: /// 我在语句中使用WHERE和NOT来排除这6个类别 当我尝试第二个方向光标时,没有出现错误。但是,Sql查

s1.ListViewCategory是Singleton类s1中的字符串类型ArrayList,它具有类别值:游戏、国家、城市、地铁、演员、宠物//在数据库中总共有33个类别,我想排除s1.ListViewCategory中的这6个类别

在rawQuery中,我想排除s1.ListViewCategory中的类别,因此我尝试了两种光标引用这两个stackoverflow问题的方法: ///

我在语句中使用WHERE和NOT来排除这6个类别

当我尝试第二个方向光标时,没有出现错误。但是,Sql查询不起作用。它必须排除字符串[params]中的类别,但它不起作用。所以我用log来看看param是什么,我得到了这个

2020-01-09 09:16:47.233 8978-8978/com.kj.word V/Tag:参数值为 游戏、国家、城市、地铁、演员、宠物

当我尝试第一个游标类别时,我得到错误日志:

public void DBSearchCategory(String tableName) {
    // 1st way 
    String inClause = s1.ListViewCategory.toString();
    inClause = inClause.replace("[", "(");
    inClause = inClause.replace("]", ")");

   //        Cursor cursor = database.rawQuery("SELECT CATEGORY FROM " + tableName
  //                + " WHERE CATEGORY NOT IN " + inClause
 //                + " ORDER BY RANDOM() LIMIT 1 ", null);

    // 2nd way
    try {
        StringBuilder sb = new StringBuilder("");
        for (String param : s1.ListViewCategory) {
            sb.append(",").append('"').append(param).append('"');
        }
        params = sb.toString().substring(1); 
        Log.v("Tag", "params value is " + params);
    } catch (StringIndexOutOfBoundsException e) {

    }
    Cursor cursor = database.rawQuery("SELECT CATEGORY FROM " + tableName
                    + " WHERE CATEGORY NOT IN (?) "
                    + " ORDER BY RANDOM() LIMIT 1 ", new String[]{params});

    while (cursor.moveToNext()) {
        category = cursor.getString(cursor.getColumnIndex("CATEGORY"));
        s1.keyCategory = category;
    }
    cursor.close();
}
我确认有一个数据库,所以我猜可能是sql查询问题

所以我的问题是,如何修复第一个或第二个游标以排除s1.ListViewCateLogy中的类别?
我找了很多,但是我找不到答案。。。如果有人回答了这个问题,我会非常感激的

在构成逗号分隔列表的循环中,将双引号改为单引号:

Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such column: game (code 1): , while compiling: SELECT CATEGORY FROM KeyWordDB WHERE CATEGORY 
NOT IN (game, country, city, subway, actor, pet) ORDER BY RANDOM() LIMIT 1)
#################################################################
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1008)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:573)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLite
此代码构造了一个类似以下内容的列表:

for (String param : s1.ListViewCategory) {
    sb.append(",").append("'").append(param).append("'");
}
params = sb.toString().substring(1); 
如果将其用作rawQuery方法中的参数,则此列表将被视为字符串文字,而不是值列表。 因此,请改为:

'game', 'country', 'city', 'subway', 'actor', 'pet'
请注意,此方法易于sql注入。 另一种方法是创建一个?占位符而不是1个占位符,并将值列表作为字符串数组传递,如下所示:

String sql = "SELECT CATEGORY FROM " + tableName
             + " WHERE CATEGORY NOT IN (?) "
             + " ORDER BY RANDOM() LIMIT 1 ";
sql = sql.replace("?", params);
Cursor cursor = database.rawQuery(sql, null);

移除try/catch块以检查是否存在任何错误。还有:Log.vTag的结果是什么,params值是+params@韩国19800在我编辑的答案中看到了另一种更安全的方法。非常感谢!我将尝试再次询问它是否有错误。如果没有错误,我也会选择你的答案!再次非常感谢该声明使用NOT,这意味着它排除了列表中必须至少有一项的所有内容,对吗?。所以要么有效要么无效。你两种方法都试过了吗?我无法重现你的问题。您必须进行调试,以在以下参数之后立即检查sql语句:sql=sql.replace?,params;并记录它的值(如果它是应该的)。
for (String param : s1.ListViewCategory) {
    sb.append(",?");
}
String[] array = ListViewCategory.toArray(new String[s1.ListViewCategory.size()]);

params = sb.toString().substring(1);
String sql = "SELECT CATEGORY FROM " + tableName
           + " WHERE CATEGORY NOT IN (@) "
           + " ORDER BY RANDOM() LIMIT 1 ";
sql = sql.replace("@", params);

Cursor cursor = database.rawQuery(sql, array);