Can anyone look into my AndroidSQLite query cursor? - android

Cursor cursor = db.rawQuery("SELECT * FROM fruits",null);
works but once I start adding restrictions like:
cursor = db.rawQuery("SELECT fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
String[] fString = {"fruitName","color","number"};
int[] tString = {R.id.fruit,R.id.color,R.id.number};
Then I keep getting an error here:
ListAdapter adapter = new SimpleCursorAdapter(
this,R.layout.newLayOutForSQL,cursor,
fString,tString,0);
I tried SELECT * FROM fruits in the db.rawQuery and it works perfectly but the restriction doesn't work
SQLiteDatabase db;
db is set up properly so no worries
cursor = db.rawQuery("SELECT fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
String[] fString = {"fruitName","color","number"};
int[] tString = {R.id.fruit,R.id.color,R.id.number};
ListAdapter adapter = new SimpleCursorAdapter(
this,R.layout.newLayOutForSQL,cursor,
fString,tString,0);
Expected: showing results with the restictions
actual results: error

The reason that you are getting errors is because not specifying *, you are excluding the _id column, which is required for CursorAdapters.
As per :-
The Cursor must include a column named "_id" or this class will not
work. Additionally, using MergeCursor with this class will not work if
the merged Cursors have overlapping values in their "_id" columns.
[CursorAdapter] (https://developer.android.com/reference/android/widget/CursorAdapter) (SimpleCursorAdapter is an indirect subclass of CursorAdapter)
Try :-
cursor = db.rawQuery("SELECT _id, fruitName, color,
number FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);
Or :-
cursor = db.rawQuery("SELECT *
FROM fruits WHERE color LIKE '%re%' AND fruitName LIKE
'%ppl%' AND number >=" + 5, null);

Related

Selecting and storing in Android's Cursor n number of rows where one row has a specific id and the rest are random

In Android Studio I'm trying to select specific amount of rows from sqlite database where one row is predetermined based on given id and the rest are picked randomly. The query should be saved in Cursor because I would display selected rows in ListView, which can take info from Cursor simply through SimpleCursorAdapter.
The initial database is created as such:
public void onCreate(SQLiteDatabase database) {
database.execSQL("CREATE TABLE DICTIONARY(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"english TEXT, " +
"estonian TEXT);");
addWordPair(database, "myriad", "tohutu hulk");
addWordPair(database, "egregious", "jõletu");
addWordPair(database, "erroneous", "väär");
addWordPair(database, "salient", "esile tõusev");
addWordPair(database, "galvanize", "laengut andma");
addWordPair(database, "tenuous", "hõre");
addWordPair(database, "caustic", "söövitav");
}
public void addWordPair(SQLiteDatabase database, String english, String estonian) {
ContentValues wordPair= new ContentValues();
wordPair.put("english", english);
wordPair.put("estonian", estonian);
database.insert("DICTIONARY", null, wordPair);
}
The selected rows would be display in ListView using Cursor:
SimpleCursorAdapter listAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
cursor,
selectedLanguage,
new int[] {android.R.id.text1},
0);
ListView listofWordsListView = (ListView) findViewById(R.id.wordsListView);
listofWordsListView.setAdapter(listAdapter);
I get five random english words using:
Cursor cursor = database.query("DICTIONARY Order By RANDOM() LIMIT 5",
new String[] {"english"}, null, null, null,null, null);
I get a single english word with specific id using:
Cursor cursor = database.query("DICTIONARY",
new String[] {"english"},
"_id = ?",
new String[] {Integer.toString(id)},
null, null, null);
Now I need to store both, the specific row and and random rows (specific row preferably in between random rows) in cursor in order to use it in CursorAdapter.
You can use a MergeCursor e.g. :-
Cursor cursor1 = database.query("DICTIONARY Order By RANDOM() LIMIT 5",
new String[] {"english"}, null, null, null,null, null);
Cursor cursor2 = database.query("DICTIONARY",
new String[] {"english"},
"_id = ?",
new String[] {Integer.toString(id)},
null, null, null);
MergeCursor merged = new MergeCursor(new Cursor[]{cursor1,cursor2});
You then treat/handle the MergeCursor (merged in this example) like a standard cursor.
MergeCursor
You can use MergeCursor to join the results of multiple Cursors into one.
In SQL, you can combine queries with a compound query:
SELECT english FROM Dictionary WHERE _id = ?
UNION ALL
SELECT * FROM (SELECT english FROM Dictionary ORDER BY random() LIMIT 5);
(Without the subquery, the ORDER BY/LIMIT would apply also to the first part.)
To put the first row into a random position, reorder again:
SELECT english FROM Dictionary WHERE _id = ?
UNION ALL
SELECT * FROM (SELECT english FROM Dictionary ORDER BY random() LIMIT 5)
ORDER BY random();
To execute a raw SQL query, use rawQuery():
Cursor cursor = database.rawQuery("SELECT .....", new String[]{ ... });

Get value of the Foreign Key in SimpleCursorAdapter

I have a listView populated with data from my db. I use a simpleCursorAdapter to show the values.
I have a table where i can add lessons : English, french...
In another table, i can create lessons developped (i add date of beginning and end, which days, a theme for the lesson). I must provide the lesson as a FK.
When I add a lesson, in my listView i want to show per example : English - Reading, but it shows 1 - Reading. Because 1 is the value i store in my 2nd table.
How can I change 1 to English ?
Here's my code :
Cursor cursor = dbhelper.getAllCours();
String[] from = { "branche_cours", "designation" }; //here 'branche_cours' is the lesson i store as an INT, it's the FK so
int[] to = { R.id.text_branche_cours, R.id.text_designation };
adapter = new SimpleCursorAdapter(this, R.layout.list_row, cursor, from, to, 0);
lvCours.setAdapter(adapter);
adapter.notifyDataSetChanged();
The method i use getAllCours()
public Cursor getAllCours()
{
//from here, i retrieve the ID, designation and branche_cours
String Query = ("select ID as _id, date_debut, date_dernier, dixieme_point, " +
"demi_point, description, designation, lundi, mardi, mercredi, jeudi," +
" vendredi, samedi, branche_cours from " + TABLE_COURS);
Open();
Cursor cursor = db.rawQuery(Query, null);
return cursor;
}
How can I link that int to the real value ( so how can the '1' become 'English')?
One solution would be to perform an SQL JOIN operation to fetch the data from both tables:
So the SQL query should be something thing like:
SELECT table1.branche_cours, table2.designation
FROM table1
INNER JOIN table2 ON table1.ID=table2.ID;
To look up a value in another table, you can use a correlated subquery:
SELECT ID AS _id,
...,
samedi,
(SELECT name
FROM other_table
WHERE other_table.id = cours.branche_cours
) AS branche_cours
FROM cours;

Android - populate ListView SQLite, cursor null pointer

I have two tables atm, users and notes. I am trying to retrieve data that belongs to the user. So all data to list must be owned by the original user and shown only to him. I have made my table in Databasehelper.
I have made a new class that controls the notes table. In listNotes() I want to loop through the cursor row and get all data owned by the user. Am I quering it correctly?
// Listing all notes
public Cursor listNotes() {
Cursor c = db.query(help.NOTE_TABLE, new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
db.close();
return c;
}
I then want to display the cursor data collected in a listview
public void populateList(){
Cursor cursor = control.listNotes();
getActivity().startManagingCursor(cursor);
//Mapping the fields cursor to text views
String[] fields = new String[]{help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE};
int [] text = new int[] {R.id.item_title,R.id.item_body, R.id.item_date};
adapter = new SimpleCursorAdapter(getActivity(),R.layout.list_layout,cursor, fields, text,0);
//Calling list object instance
listView = (ListView) getView().findViewById(android.R.id.list);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
}
You aren't creating the NOTE_TABLE right.
You miss a space and a comma here
+ COLUMN_DATE + "DATETIME DEFAULT CURRENT_TIMESTAMP"
It has to be
+ COLUMN_DATE + " DATETIME DEFAULT CURRENT_TIMESTAMP,"
There are two issues here:
One is you have missed a comma (after the Timestamp as specified in an earlier answer).
The other error you have is when using a SimpleCursorAdapter, you need to ensure that the Projection string array includes something to index the rows uniquely and this must be an integer column named as "_id". SQLite already has a feature built in for this and provides a column named "_id" for this purpose (however you can have your own integer column which you can rename to _id). To solve this, change your projection string array to something like:
new String[] {"ROW_ID AS _id", help.COLUMN_TITLE,help.COLUMN_BODY, help.COLUMN_DATE}
I guess the NullPointerException stems from this (but without the stacktrace I don't know for sure).

how to retrieve the sum of column values in simplecursoradapter in sqlite database

Am using db query to sum the column values by using group by clause. I can get the total amount but i couldn't display the values in simplecursoradapter. Please help me to display the total values. I have posted my code below.
String[] columns = new String[] { KEY_ID, KEY_CATEGORY,"sum("+KEY_AMOUNT+")as" + KEY_AMOUNT,
KEY_COMMENT };
Cursor cursor = db.query(TABLENAME2, columns, null, null, null, null,
null);
return cursor;
To display the values in Listview using Simplecursoradapter
String[] from = new String[] { Dailydialog.KEY_CATEGORY,
Dailydialog.KEY_AMOUNT,Dailydialog.KEY_COMMENT};
int[] to = new int[] { R.id.id2, R.id.id3,R.id.id4};
cursorAdapter1 = new SimpleCursorAdapter(this, R.layout.dailydialogall, cursor1,
from, to);
listview_dialog.setAdapter(cursorAdapter1);
Total values are not listed in Listview.
Instead of "sum("+KEY_AMOUNT+")as" + KEY_AMOUNT use " sum("+KEY_AMOUNT+") as " + KEY_AMOUNT. Notice the spaces? Its always a good idea to print your query in log. Another thing is that you need to specify group by clause as well for sum function otherwise only one row will be returned with total sum of amount of all the rows.

android sqlite listview cursor problem

From my main.java:
Cursor c = db.getDue();
String[] columns = new String[] { "_id", "date" };
int[] to = new int[] { R.id.num, R.id.date };
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.lventer, c, columns, to);
ListView lv1 = (ListView)findViewById(R.id.ListView01);
lv1.setAdapter(mAdapter);
From my database wrapper class:
public Cursor getDue() {
//String getdue = "SELECT * FROM tb1"; // this returns _id+date and displays them in the listview via the cursor adapter, defined above
String getdue = "SELECT _id, max(date) AS date FROM tb1 GROUP BY _id";// this only works if I remove the "date" bindings defined above, only letting me see the _id, i want to see both _id and date in the lit view.
return db.rawQuery(getdue,null);
If I use the second select statment then it crashes unless I remove the "date" from the cursor adapter/listview bindings, if I do this then It will show the returned _id in the listview, but I want to see both _id and date in the listview.
I have been told that the second statment might returns a different type for date because of the max function ( I am not very sql literate, yet), but I thought that sqlite was loose with datatypes? Can anybody help, thanks in advance.
** UPDATE** This is the command that wont work with 2 columns fr the list view:
SELECT _id, max(date) FROM jobs GROUP BY _id HAVING max(date) < (date-21)
Use this:
String getdue = "SELECT _id, max(date) AS date FROM tb1 GROUP BY _id";

Categories

Resources