Как использовать операторы tow в запросе оператора SQLite? - PullRequest
0 голосов
/ 15 июня 2019

Я запрашиваю из базы данных SQLite, где мне нужно объединить два оператора «И» и «ИЛИ» в одном запросе, используя приведенный ниже код. Курсор не возвращает данные. Как я могу использовать операторы буксировки в запросе?

    String[] selectedTopics = getSelectedTopics();
    String[] selectedArgs = new String[selectedTopics.length + 3];

    String selection = "(" + COLUMN_FOREIGN_WORDS_DIFFICULTY + " = ? AND " 
        +   COLUMN_FOREIGN_WORDS_IS_SELECTED + " = ? AND "  
        +   COLUMN_FOREIGN_WORDS_IS_REJECTED + " = ? ) AND (";
    for (int i = 0; i < (selectedTopics.length); i++) {
        if (i != (selectedTopics.length - 1)) {
            selection += "topic = ? OR ";
        } else {
            selection += "topic = ? ) ";
        }
    }

    selectedArgs[0] = String.valueOf(difficulty);
    selectedArgs[1] = "0";
    selectedArgs[2] = "0";
    int k = 0;
    for (int j = 3; j < selectedArgs.length; j++) {
        selectedArgs[j] = selectedTopics[k];
        k++;
    }

    Log.i(TAG, "getNewWordsToLearn: selection = " + selection);
    Log.i(TAG, "getNewWordsToLearn: selectionsArgs = " + 
           Arrays.toString(selectedArgs));

   Cursor c = database.query(TABLE_NAME_FOREIGN_WORDS,null, selection, 
      selectedArgs, null, null, null);

Журнал показывает: -

2019-06-15 14:25:43.634 15564-15590/com.marzoq.vocabuilder I/DBQueries: getNewWordsToLearn: selection = (difficulty = ? AND isSelected = ? AND isRejected = ? ) AND (topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? )     
2019-06-15 14:25:43.634 15564-15590/com.marzoq.vocabuilder I/DBQueries: getNewWordsToLearn: selectionsArgs = [1, 0, 0, Appearance, Eating out, Environment, Food, Health, Home, Leisure, People, Politics, Reference, Services, Sports, Study, Transport, Work]
2019-06-15 14:25:43.641 15564-15590/com.marzoq.vocabuilder I/TestRunner: failed: getNewWordsToLearn(com.marzoq.vocabuilder.DBQueriesTest)

«Я ожидаю, что c.getCount> 0, но этого никогда не произойдет, используя приведенный выше запрос»

1 Ответ

0 голосов
/ 16 июня 2019

Я считаю, что ваша проблема - неправильное понимание логики.Это предполагает, что данные в базе данных, такие как (в соответствии с приведенным ниже примером): -

  1. Difficulty = 1, IsRejected = 0, IsSlected 0, Topic = "People"
  2. Difficulty = 1, IsRejected = 0, IsSlected 0, Topic = "Leisure"
  3. Difficulty = 1, IsRejected = 0, IsSlected 0, Topic = "Not a Listed Topic"
  4. Difficulty = 1, IsRejected = 1, IsSlected 0, Topic = "People"
  5. Difficulty = 1, IsRejected = 0, IsSlected 1, Topic = "People"
  6. Difficulty = 1, IsRejected = 1, IsSlected 1, Topic = "People"
  7. Difficulty = 2, IsRejected = 0, IsSlected 0, Topic = "People"

Наряду со списком выбранныхтемы: -

  • Внешний вид, Питание, Окружающая среда, Питание, Здоровье, Дом, Досуг, Люди, Политика, Справочные материалы, Услуги, Спорт, Учеба, Транспорт, Работа

Тогда только 1 и 2 будут SELECT отредактированы как: -

  • Сложность равна 1
  • И IsRejected равно 0
  • И IsSelected0
  • И темы Люди / Досуг находятся в списке выбранных тем

3-7 Не будут извлечены как: -

  • Не указанная тема не является темой в списке, поэтому AND (Topic = ? OR ......) является ложным (не соответствует действительности)
  • IsRejected не равно 0, поэтому AND isRejected ложно, поэтому 3 И в скобках ложно и, следовательно, общий результат ложен.
  • IsSelected не равно 0 (такой же результат, как у 4)
  • Оба IsRejected и IsSelected ложны (следовательно, тот же результат, что и 4)
  • Сложность не равна 1 (аналогично результату 4).

Обычно при использовании AND обе стороны выражения должны быть ИСТИНА, чтобы выражение имело значение ИСТИНА.

Выше тестировалось с использованием слегка измененной версии вашего кода в соответствии с: -

public void doit(int difficulty, String[] topicsSelected) {

    String TAG = "DBQueries";
    String[] selectedTopics = topicsSelected; //<<<<<<<<<< get the topics from parameter passed
    String[] selectedArgs = new String[selectedTopics.length + 3];

    String selection = "(" + COLUMN_FOREIGN_WORDS_DIFFICULTY + " = ? AND "
            + COLUMN_FOREIGN_WORDS_IS_SELECTED + " = ? AND "
            + COLUMN_FOREIGN_WORDS_IS_REJECTED + " = ? ) AND (";
    for (
            int i = 0; i < (selectedTopics.length); i++) {
        if (i != (selectedTopics.length - 1)) {
            selection += "topic = ? OR ";
        } else {
            selection += "topic = ? ) ";
        }
    }

    selectedArgs[0] = String.valueOf(difficulty);
    selectedArgs[1] = "0";
    selectedArgs[2] = "0";
    int k = 0;
    for (
            int j = 3;
            j < selectedArgs.length; j++) {
        selectedArgs[j] = selectedTopics[k];
        k++;
    }

    Log.i(TAG, "getNewWordsToLearn: selection = " + selection);
    Log.i(TAG, "getNewWordsToLearn: selectionsArgs = " +
            Arrays.toString(selectedArgs));

    Cursor c = database.query(TABLE_NAME_FOREIGN_WORDS, null, selection,
            selectedArgs, null, null, null);
    //<<<<<<<<<< ADDED CODE
    Log.i(TAG,"Number of rows extracted is " + String.valueOf(c.getCount()));
    while (c.moveToNext()) {
        Log.i(TAG,"Extracted row is:-  Topic is " + c.getString(c.getColumnIndex(COLUMN_FOREIGN_WORDS_TOPIC))   );
    }
}
  • См. Комментарии для изменений

Наряду со следующимметод (также в классе Database Helper), позволяющий добавить некоторые данные тестирования: -

public long add(int difficulty, boolean rejected, boolean selected, String topic) {
    ContentValues cv = new ContentValues();
    cv.put(COLUMN_FOREIGN_WORDS_DIFFICULTY,difficulty);
    cv.put(COLUMN_FOREIGN_WORDS_IS_REJECTED,rejected);
    cv.put(COLUMN_FOREIGN_WORDS_IS_SELECTED,selected);
    cv.put(COLUMN_FOREIGN_WORDS_TOPIC,topic);
    return database.insert(TABLE_NAME_FOREIGN_WORDS,null,cv);
}

Затем в Activity было использовано следующее, чтобы добавить некоторые данные и затем вызвать ваш код (doit method): -

public class MainActivity extends AppCompatActivity {

    DBHelper002 mDBHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBHelper = new DBHelper002(this);
        String[] selectedtopics = new String[]{"Appearance", "Eating out", "Environment", "Food", "Health, Home", "Leisure", "People", "Politics", "Reference", "Services", "Sports", "Study", "Transport", "Work"};
        mDBHelper.add(1,false,false,"People");
        mDBHelper.add(1,false,false,"Leisure");
        mDBHelper.add(1,false,false,"Not a Listed Topic"); // Not Extracted as Not a Listed Topic is not one of the selected topics
        mDBHelper.add(1,true,false,"People"); //Not extracted as rejected is true (not 0) otherwise it would be selected
        mDBHelper.add(1,false,true,"People"); //Not extracted as selected is true (not 0) otherwise it would be selected
        mDBHelper.add(1,true,true,"People"); //Not extracted as rejected is true (not 0) and because selected is true
        mDBHelper.add(2,false,false,"People"); //Not Extracted as difficulty is not 1 otherwise is would be selected
        mDBHelper.doit(1,selectedtopics);
    }
}

Результаты: -

06-16 07:07:17.932 32648-32648/? I/DBQueries: getNewWordsToLearn: selection = (diff = ? AND selected = ? AND rejected = ? ) AND (topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? OR topic = ? ) 
06-16 07:07:17.932 32648-32648/? I/DBQueries: getNewWordsToLearn: selectionsArgs = [1, 0, 0, Appearance, Eating out, Environment, Food, Health, Home, Leisure, People, Politics, Reference, Services, Sports, Study, Transport, Work]
06-16 07:07:17.932 32648-32648/? I/DBQueries: Number of rows extracted is 2
06-16 07:07:17.932 32648-32648/? I/DBQueries: Extracted row is:-  Topic is People
06-16 07:07:17.932 32648-32648/? I/DBQueries: Extracted row is:-  Topic is Leisure
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...