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