2015-04-24 5 views
0

Привет В настоящее время у меня есть база данных, содержащая 5 вопросов и ответов, хранящихся в ней. Я хочу случайным образом выводить три вопроса каждый раз, когда приложение запускается. У меня есть ниже код, но мое приложение вылетает при загрузкеСоздание случайного вывода из базы данных SQLite

public List<Question> getAllQuestions() { 
     List<Question> quesList = new ArrayList<Question>(); 
     int nQuestions = 3; //select COUNT(*) from questions 

     Random random = new Random(); 
     int id = random.nextInt(nQuestions); 

     String selectQuery = "SELECT id FROM " + TABLE_QUEST; 
     dbase=this.getReadableDatabase(); 
     Cursor cursor = dbase.rawQuery(selectQuery, null); 
     // looping through all rows and adding to list 
     if (cursor.moveToFirst()) { 
      do { 
       Question quest = new Question(); 
       quest.setID(cursor.getInt(0)); 
       quest.setQUESTION(cursor.getString(1)); 
       quest.setANSWER(cursor.getString(2)); 
       quest.setOPTA(cursor.getString(3)); 
       quest.setOPTB(cursor.getString(4)); 
       quest.setOPTC(cursor.getString(5)); 
       quesList.add(quest); 
      } while (cursor.moveToNext());{ 
       id = random.nextInt(nQuestions); 
      } 
     } 
     // return quest list 
     return quesList; 
    } 
+0

Вы видите какие-либо исключения, когда приложение выходит из строя? Содержит ли код? – CKing

ответ

0

Проблема заключается в том, что вы выбрали только идентификатор из таблицы, для всех записей.

Ваш случайный будет также выбирать только вопросы 0, 1 или 2. Ваш случайный должен быть random.nextInt(5), так как у вас есть 5 вопросов.

Наконец, это должно быть в цикле, а затем добавить несколько запросов к вашему запросу, чтобы получить несколько вопросов.

String query = "SELECT * FROM " + TABLE_QUEST + " WHERE "; 
    for (int x = 0; x < nQuestions; x++) { 
     if (x > 0) { 
      query += " OR "; 
     } 
     query += "id=" + random.nextInt(5); 
    } 

Это сделает ваш запрос выглядеть следующим образом:

SELECT * FROM TABLE_QUEST WHERE id=4 OR id=2 OR id=3 

Наконец, изменить ваше cursor.moveToNext() есть. Ваш код должен выглядеть примерно так:

public List<Question> getAllQuestions() { 
    List<Question> quesList = new ArrayList<Question>(); 
    int nQuestions = 3; //select COUNT(*) from questions 

    Random random = new Random(); 

    String query = "SELECT * FROM " + TABLE_QUEST + " WHERE "; 
    for (int x = 0; x < nQuestions; x++) { 
     if (x > 0) { 
      query += " OR "; 
     } 
     query += "id=" + random.nextInt(5); 
    } 

    dbase=this.getReadableDatabase(); 
    Cursor cursor = dbase.rawQuery(query, null); 
    // looping through all rows and adding to list 
    if (cursor.moveToFirst()) { 
     do { 
      Question quest = new Question(); 
      quest.setID(cursor.getInt(0)); 
      quest.setQUESTION(cursor.getString(1)); 
      quest.setANSWER(cursor.getString(2)); 
      quest.setOPTA(cursor.getString(3)); 
      quest.setOPTB(cursor.getString(4)); 
      quest.setOPTC(cursor.getString(5)); 
      quesList.add(quest); 
     } while (cursor.moveToNext()); 
    } 
    // return quest list 
    return quesList; 
} 
+0

Спасибо Замерсон! Я просто получаю одну ошибку при selectQuery? –

+0

O изменить имена переменных ха-ха. Я копирую и вставляю ваш код, а затем копирую и вставляю мою, не сопоставляя имена переменных. У меня есть 'String query ...', тогда как в rawQuery это 'rawQuery (selectQuery, null)'. Просто введите эти два имени переменной. Я обновлю свой код, чтобы это отразить. – Zamereon

+0

О, я вижу, спасибо. Он создает случайные вопросы, однако, после ответа на 3 вопроса, которые он выталкивает меня из приложения, тогда как перед ним загружалась другая страница? У вас есть идеи? –

1

Извините, что я пишу это как ответ, но у меня нет разрешения на запись комментариев к вопросу, так что я хочу вам сказать, что первый из всех вы всегда станете одним из первых 3 добавленных вопросов в качестве случайного вопроса, потому что для случайного идентификатора вы используете в качестве ограничений 3 id = random.nextInt(nQuestions); вместо nQuestions (что для вас 3, вы должны использовать questList.size() и делать это 3 раза для номера от 0 до questList.size()

0

В коде есть пара ошибок.

Во-первых, ваш SQL-запрос неправильно:

String selectQuery = "SELECT id FROM " + TABLE_QUEST; 

дает все значения столбца «ID» в таблице TABLE_QUEST, а не столбец с id вы определили с вашим вызовом Random.nextInt ,

String selectQuery = "SELECT * FROM " + TABLE_QUEST + " WHERE id=" + id; 

Символ «*» означает «все столбцы в этой таблице» и «WHERE» позволяет фильтровать строки в соответствии с условиями, которые следуют (т.е. идентификатор = 3).

Примечание в то время как это не является проблемой в этом случае, переходя неэкранированные значения (т.е. WHERE id=" + id часть очень плохой форме, потому что это может сделать вас уязвимыми для инъекций SQL, как только вы используете пользовательский ввод для этого).

Второй: остальная часть кода не имеет большого смысла по разным причинам. Я попытаюсь перечислить некоторые из них:

  • если ваш код будет работать (т.е. с * вместо идентификатора в SELECT, но без предложения WHERE), вы бы просто добавить все вопросы в базе данных к списку, потому что нет никаких условий.
  • Если условие будет работать, вы получите только одну строку с определенным идентификатором. ваш цикл while-while будет работать только один раз.
  • Если у вас был цикл вокруг выбора, тогда он может работать, но он, вероятно, вернет те же строки TWICE или даже чаще.
  • вы все равно получите случайные сбои по разным причинам, среди них
    • первичных ключей - атрибут ID, который, вероятно, автоинкрементный - это не обязательно в пределах 0..n-1. это может быть в вашем случае, но это не совсем типично. автоматически увеличивающиеся первичные ключи обычно начинаются с 1.
    • , если ваши ответы на вопросники CRUD (создание, чтение, обновление, удаление), идентификаторы могут иметь отверстия, то есть «1, 2, 6, 8, 12».

я бы переписать весь метод; есть несколько способов сделать это. лишь несколько советов:

  1. если есть очень мало записей в таблице (например, менее чем за пару сотен), вы можете просто загрузить все вопросы в список А.
    1. списка Создать
    2. надстройку все записи из базы данных перечислить
    3. создать список B
    4. до тех пор, как есть в списке B меньше элементов, чем вы хотите (т.е. listB.size() < 3) удалить произвольный элемент из списка а и добавить его в список Б.
    5. return listB. // Это кажется расточительным, но, вероятно, будет в порядке.
  2. пусть базы данных делать рандомизации:
    1. SELECT * FROM таблицы ORDER BY RANDOM() LIMIT 3;
    2. прочитать все записи в список
    3. вернуть список
    4. сделано! (примечание: это работает с sqlite, но, насколько мне известно, не универсально принято различными системами баз данных).

есть множество других способов достижения этой цели. но я бы просто использовал трюк ORDER BY RANDOM() LIMIT x, это, наверное, самый простой способ.

Смежные вопросы