Android - sqlite в предложении, используя строковые значения из arraylist? - PullRequest
1 голос
/ 09 января 2020
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();
}
  1. s1.ListViewCategory является строковым типом ArrayList в классе Single1 s1 и имеет значения категорий: "игра", "страна", "город", "метро", "актер" "," pet "// В базе данных всего 33 категории, и я хочу исключить эти 6 категорий из s1.ListViewCategory

  2. В rawQuery я хочу исключить категории, которые находятся в s1.ListViewCategory, поэтому я попробовал 2 способа указания курсора на эти 2 вопроса stackoverflow: Android - sqlite в предложении, используя строковые значения из массива? /// Android - sqlite в предложении, используя значения из массива

Я использовал оператор WHERE и NOT IN, чтобы исключить эти 6 категорий

Когда я попробовал 2-сторонний курсор, я не получил ошибку. Однако запрос Sql не сработал. Он должен был исключить категории, которые есть в String [params], но это не сработало. Поэтому я использовал log, чтобы увидеть, что такое param, и получил это

2020-01-09 09: 16: 47.233 8978-8978 / com.kj.word V / Tag: значение params равно "game", " страна "," город "," метро "," актер "," домашнее животное "

Когда я попробовал 1-ую категорию курсоров, я получил сообщение logcat:

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

Я подтвердил, что база данных существует, поэтому, вероятно, это sql проблема с запросом ...

Так что мой вопрос: как я могу исправить первый или второй курсор, чтобы исключить категории, которые есть в s1.ListViewCateogry?

Я очень усердно искал, но не смог найти ответ ... Буду очень благодарен, если кто-то ответит на этот вопрос

1 Ответ

0 голосов
/ 09 января 2020

Измените двойные кавычки с одинарными кавычками внутри l oop, который составляет список с разделителями-запятыми:

for (String param : s1.ListViewCategory) {
    sb.append(",").append("'").append(param).append("'");
}
params = sb.toString().substring(1); 

Этот код создает список, например:

'game', 'country', 'city', 'subway', 'actor', 'pet'

Если вы используйте его в качестве параметра в методе rawQuery(), тогда этот список будет обрабатываться как строковый литерал, а не как список значений. Так что сделайте это вместо:

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

Обратите внимание, что этот метод склонен к sql инъекции. Другой способ - создать список ? заполнителей вместо 1 заполнителя и передать список значений в виде массива строк, например:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...