Android: Проблема с запросом SQLite

#android #sqlite

#Android #sqlite

Вопрос:

У меня есть база данных, содержащая таблицу Animal со столбцами для _id, имени, биографии.

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

Кто-нибудь может увидеть, в чем может быть проблема, или предложить несколько полезных предложений, я был бы очень признателен.

  // Code for obtaining position
protected void onListItemClick(ListView l, View v, int position, long id){
        Intent animalIntent = new Intent(this, Animal.class);
        animalIntent.putExtra("pos", position);
        startActivity(animalIntent);    
    }
  

// запросите базу данных для bio, где KEY_ROWID запрашивается по «позиции» элемента в списке.
myCursor = dbm.getBio(позиция);

     if(myCursor.moveToFirst()){

    // querying the cusor, retrieve in index of column BIOGRAPHY, store as column index.
        int bio_index = myCursor.getColumnIndexOrThrow(MyDBManager.KEY_BIOGRAPHY);

        // return the string from the cursor @ column index
    String bio = myCursor.getString(bio_index);

    // find textview 
        animalBio = (TextView)findViewById(R.id.bio);

        // Set textView to value of string returned from myCursor @ bio_index
    animalBio.setText(bio);
    }
  

// Этот метод всегда будет возвращать первое значение, сохраненное в биографии базы данных, хранящейся в базе данных
общедоступный курсор getBio (int position){

     return qmDB.query(ANIMAL_TABLE, new String[]{
            KEY_ROWID,
            KEY_BIOGRAPHY,
            },
            KEY_ROWID,
            null,
            null,
            null,
            null);
}
  

Я пробовал другие варианты, такие как KEY_ROWID = » » = позиция, KEY_ROWID = «?», преобразование позиции в строку, передача позиции как типа long, жесткое кодирование числа и т.д.

Итак, вы видите, я чувствую, что проблема в операторе запроса, он просто не возвращает никакой другой строки, кроме первой, или, если возвращает, она не отображается!

РЕШЕНИЕ:

Не забудьте обновить свою базу данных в приложении.

Комментарии:

1. Не могли бы вы, пожалуйста, предоставить код для получения position ?

2. конечно, пекка, я обновил исходный пост кодом, а также некоторыми новыми объяснениями того, как я подошел к проблеме.

3. Мне удалось решить проблему, как оказалось, я не обновлял базу данных.4 дня и бесчисленные часы разочарований, не собираюсь забывать об этом в спешке … спасибо всем за полезный совет.

Ответ №1:

Как и в результирующем наборе JDBC, вам нужно вызвать метод ‘moveToNext ()’ для перемещения вашего курсора. Пример:

 while(myCursor.moveToNext()){
   bio = myCursor.getString(bio_index);
   // etc...
}
  

Курсор JavaDoc: http://developer.android.com/reference/android/database/Cursor.html

общедоступный абстрактный логический moveToNext ()

Поскольку: Уровень API 1

Переместите курсор на следующую строку. Этот метод вернет false, если курсор уже прошел последнюю запись в результирующем наборе.

Возвращает: удалось ли перемещение

Комментарии:

1. Привет, Висенте, нет необходимости использовать moveToNext (), поскольку я хочу вернуть только одну биографию определенного выбранного животного. Работа приложения выглядит следующим образом: Список животных -> страница животных (включая изображение и кнопки «биография» и «назад») -> страница биографии животного. Итак, вы видите, я запрашиваю базу данных на основе положения животного в списке. Я использую эту позицию для сопоставления с полем _ID в таблице и возврата соответствующей биографии.

2. Понял. Можем ли мы увидеть ваш обработчик списка?

3. По listHandler вы говорите об активности со списком? Я провел тест, чтобы проверить, правильно ли передается позиция, и все оказалось в порядке.

4. Тогда, я думаю, вам следует проверить, что KEY_ROWID ссылается на соответствующий столбец. И (это не должно повлиять на результат, но кто знает) с использованием 4-го параметра, который похож на setParameter из результирующего набора (вы также можете использовать вопросительные знаки здесь). Я также думаю, что вы что-то упускаете в своем примере кода, потому что массив закрывается сразу после запятой, AFAIK это недопустимый синтаксис Java.

Ответ №2:

сделайте что-то вроде этого:

 Cursor c=null;
c=;
try {
if (c!=null) {
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {

}

}
} finally {
if (c!=null) {
c.close();
}
}
  

Комментарии:

1. Привет, Pentium, я пытался исправить проблему с помощью этого кода, и это не сработало! Я могу получить доступ к базе данных без проблем, и она вернет мне информацию. У меня просто складывается ощущение, что проблема связана с идентификатором строки и расположением элемента списка..

2. У нас нет информации о position . Если моя догадка верна, это, вероятно, порядковый номер из списка выбора. Вам нужно переместить ваш адаптер в эту позицию и получить уникальный идентификатор записи в этой позиции, а также передать уникальный идентификатор, а не позицию.

3. Ваша догадка была бы правильной, однако я не использую адаптер, скорее я использую приведенный выше код для возврата курсора, получения индекса столбца biography и установки TextView в значение biography . Возможно ли это сделать таким образом?

4. Как уже было сказано, мы не знаем, какие значения (откуда) position получает. Но, возможно, это не уникальный идентификатор, и в этой ситуации вам нужно использовать LIMIT OFFSET,1 синтаксис, чтобы пропустить X строк с самого начала. position В этом синтаксисе будет смещение, и оно будет равно нулю для первой строки. Надеюсь, это поможет.

Ответ №3:

Я думаю, проблема заключается в том, как вы создаете свой sql-запрос. Следующий код должен решить вашу проблему.

 public Cursor getBio(int position) {
    return qmDB.query(ANIMAL_TABLE, new String[]{KEY_ROWID,KEY_BIOGRAPHY}, "KEY_ROWID=?",  new String[]{ position }, null, null, null);
}
  

Комментарии:

1. Привет, Раунак, Спасибо за предложение, я пробовал этот подход и, к сожалению, он не сработал!

Ответ №4:

Это может показаться оскорбительным, но используйте sqlitebrowser и убедитесь, что ваш уникальный идентификатор действительно уникален (возможно, вы забыли автоинкрементировать?) Ваш существующий код выглядит нормально.

Комментарии:

1. Привет, Ян, в моей инструкции create включено автоматическое увеличение, и я знаю, что существует более одной строки, поскольку список заполнен несколькими животными из одной таблицы.

2. я думаю, вы отредактировали свой метод запроса. Третий параметр обязательно должен быть (KEY_ROWID «=» position), если вы не используете ? отметьте синтаксис.

3. Да, вы правы! С моим запросом вообще не было проблем, оказывается, вся проблема была основана на устаревшей базе данных bing ..grr.

4. хм, ну, пожалуйста, завершите эту тему, предоставив свое решение в ответе.

Ответ №5:

Поскольку вы сказали, что у вас есть список, я предполагаю, что вы используете метод onListItemClick. Итак, получите имя (позиция 1 в соответствии с вашей таблицей) элемента, на который нажал пользователь.

 @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        Cursor o = (Cursor) this.getListAdapter().getItem(position);
        dbm.getBio(o.getString(1));
    }
  

На мой взгляд, ваш запрос, использующий позицию, ошибочен. Это то, что, я думаю, вы хотите сделать в своем методе getBio:

 public Cursor getBio(String name) {
    return this.dbm.query(ANIMAL_TABLE, new String[]{KEY_BIOGRAPHY},"name='"   name   "'", null, null, null, null);
}