Wpis z mikrobloga

Mirki, jest taki problem. Mam bazę SQLite. W tej bazie w tabeli są 2 rekordy (dowód z załączonym obrazku). Teraz na pierwszym fragmencie mam Spinner, który mi te rekordy wypisuje w formie listy (i tu jest ok). Problem zaczyna się gdy wybiorę drugi element z listy. Wtedy następuje wywołanie fragmentu mającego na celu wyświetlenie szczegółów wybranego elementu. Oczywiście odpowiednio przekazuję ID wybranego elementu (w tym przypadku ID=3). W metodzie zwracającej obiekt z bazy danych korzystam z Cursora, jak niżej:

Cursor cursor = database.rawQuery(query, null);
Problem w tym, że po wywołaniu tej metody obiekt cursor nie zawiera szukanego elementu: cursor.getLength() zwraca 0.

Najciekawsze jest to, że jeżeli wybiorę PIERWSZY element z listy (ID=1) to database.rawQuery(query, null) zwraca poprawny rekord. W obu przypadkach korzystam z tej samej metody pobierającej dane i zapytania sql są dokładnie identyczne (różnią się tylko ID w klauzuli where). Jako dowód oba zapytania poniżej:

SELECT e._id AS Id, e.details AS Details, e.date AS Date, e.amount AS Amount, p.id AS PaymentTypeId, p.name AS Payment, c._id AS CategoryId, c.name AS Category FROM expenses e INNER JOIN payments p ON e.payment_id = p.id INNER JOIN categories c ON e.category_id = c._id WHERE Id = 1
SELECT e._id AS Id, e.details AS Details, e.date AS Date, e.amount AS Amount, p.id AS PaymentTypeId, p.name AS Payment, c._id AS CategoryId, c.name AS Category FROM expenses e INNER JOIN payments p ON e.payment_id = p.id INNER JOIN categories c ON e.category_id = c._id WHERE Id = 3
Ktoś wie dlaczego nie znajduje drugiego elementu?

#programowanie #android
markaron - Mirki, jest taki problem. Mam bazę SQLite. W tej bazie w tabeli są 2 rekor...

źródło: comment_lJTvZjYXFmxHRzzGg3RvfTm4T1LQ8aHv.jpg

Pobierz
  • 10
  • Odpowiedz
@markaron: Poniższe zapytania generuje ci jeden wpis z id=3?

SELECT e.
id AS Id, e.details AS Details, e.date AS Date, e.amount AS Amount, p.id AS PaymentTypeId, p.name AS Payment, c.id AS CategoryId, c.name AS Category FROM expenses e INNER JOIN payments p ON e.paymentid = p.id INNER JOIN categories c ON e.categoryid = c.id WHERE Id = 3
  • Odpowiedz
@vipkop: Nie bardzo rozumiem o co Ci chodzi z tym generowaniem. W skrócie są 2 rekordy w bazie o id=1 i id=3. To samo zapytanie dla warunku WHERE id=1 zwraca wynik, dla WHERE id=3 już nie. Tak jakby patrzył do innej bazy. Poniższy zrzut ekranu jest z katalogu: data/data/nazwaprojektu/databases/nazwabazy.db
  • Odpowiedz
@markaron: Rozumiem o co ci chodzi. Pytanie co nie zwraca wyniku? Zapytanie SQL czy dana metoda? Rozumiem, że napisałeś sobie query w SQL, a następnie wrzucasz to query do metody rawQuery, aby pobrać wpis? Dlatego zapytałem czy samo zapytanie sql zwraca ci wynik dla id=3? Jeżeli nie to przynajmniej wiadomo, że problem nie leży w metodzie tylko samym zapytaniu. Może piszę tu banały, ale czytając twój post nie bardzo można było
  • Odpowiedz
@vipkop: Wygląda, że zapytanie nie zwraca wyniku - tak jakby nie istniał w bazie do której się łączę, co byłoby dziwne bo takie dane w tej bazie są. Zapytanie samo w sobie jest ok, bo mam przygotowane wcześniej zapytanie dla całej tabeli, tylko doklejam warunek w zależności po czym chcę filtrować.

Zresztą zapytania które podałem są już tymi które lecą do rawQuery
  • Odpowiedz
@markaron: Więc możliwe, że problem leży w strukturze bazy danych i INNER JOIN. Łączysz, że sobą tabele. Za pomocą INNER JOIN otrzymujesz iloczyn zbioru, więc jeżeli wpis w tabelach, które łączysz ma NULL to nie pokaże tobie tego wyniku. Wtedy potrzebujesz np. OUTER JOIN (left lub right). To jest moja spekulacja, bo żeby z pewnością to stwierdzić musiałbym zobaczyć Twoją bazę danych, a nie jej wycinek.
  • Odpowiedz
@markaron: Z drugiej strony napisałeś, że warunek WHERE dopiero wprowadza ten problem, więc samo złączenie pokazuje ci dwa wyniki. Sorry, nie doczytałem.

Inaczej, czy Twoje zapytanie bez WHERE pokazuje ci dwa wyniki?
  • Odpowiedz
@vipkop: Tak, dokładnie. Napisałem w pierwszym poście, że kontrolka Spinner pokazuje dwa rekordy. Dodam, że do tego zapytania, który wyświetla dwa rekordy doklejam po prostu warunek, coś w stylu:

ExpensesTable.SELECT_ALL_SQL + " WHERE Id = " + id
  • Odpowiedz
@markaron: No tak piszesz o kontrolce, ale kontrolka już wyświetla "przetworzone" dane. Czyli pobrane z jakieś metody.

Masz jakiś edytor w tym SQLlite - edytor zapytań SQL (sam nie programuje w androidzie). Chodzi o to, żebyś wkleił samo

SELECT e.id AS Id, e.details AS Details, e.date AS Date, e.amount AS Amount, p.id AS PaymentTypeId, p.name AS Payment, c.id AS CategoryId, c.name AS Category FROM expenses e INNER JOIN payments
  • Odpowiedz
@vipkop: Znalazłem problem, okazuje się być dość trikowy. SQLite nie uznaje robienia warunku po aliasie kolumny. Czyli zamiast:

SELECT e._id AS Id, e.details AS Details, ... FROM expenses e INNER JOIN payments p ON e.payment_id = p.id INNER JOIN categories c ON e.category_id = c._id WHERE Id = 1
należy zrobić:

SELECT e._id AS Id, e.details AS Details, ... FROM expenses e INNER JOIN payments p ON e.payment_id = p.id INNER
  • Odpowiedz