I am using SQLite in Android.
I have the query, query executed and how to print count from cursor.
Cursor dataCount = mDb.rawQuery("select count(*) from " + DATABASE_JOURNAL_TABLE, null);
I have no record in table.
You already have the correct approach.
Cursor cursor = database.rawQuery("select count(*) from " + DATABASE_JOURNAL_TABLE, null);
// ensure there is at least one row and one column
if (cursor.getCount() > 0 && cursor.getColumnCount() > 0) {
cursor.close();
return cursor.getInt(0);
} else {
cursor.close();
return 0;
}
You must check that there is at least 1 row and 1 column, if you provide a table that does not yet exist there will be no column to access and cursor.getInt(0) will throw an exception.
source: https://github.com/samkirton/SQLKing
May be by getInt(index) as
cursor.getInt(1); // this is for example, you have to adjust index in your code
Also cursor has a built in function getCount() to return row number so can also do like this:
// assuming your table has `id` column as primary key or unique key.
Cursor dataCount = mDb.rawQuery("select id from " + DATABASE_JOURNAL_TABLE, null);
dataCount.getCount();
See android devloper's doc for Cursor for more information.
Related
So I have a filled in Database with the columns: _ID, excersise, reps and timestamp. Im trying to print out the row with the highest rep number of an excersise with this Cursor:
private Cursor getRepRecord(String excersise) {
return myDatabase.query(Contact.ExcersiseEntry.TABLE_NAME,
new String [] {"MAX(reps)"},
Contact.ExcersiseEntry.EXCERSISE_NAME + "= '" + excersise + "'",
null,
null,
null,
Contact.ExcersiseEntry.EXCERSISE_REPS + " DESC");
}
and then I use this method to print the cursor rows:
private void getEntryFromDatabase(Cursor cursor) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String excersise = cursor.getString(cursor.getColumnIndex(Contact.ExcersiseEntry.EXCERSISE_NAME));
int reps = cursor.getInt(cursor.getColumnIndex(Contact.ExcersiseEntry.EXCERSISE_REPS));
int id = cursor.getInt(cursor.getColumnIndex(Contact.ExcersiseEntry._ID));
Log.i("Entry", "ID: " +id + " || Excersise: " + excersise + " || reps: " + Integer.toString(reps));
cursor.moveToNext();
}
}
How ever I get the Error: CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 1 columns. I know there are alot of similar questions but I looked at man and still couldn´t find the Solution...
The reason why you are getting the -1 is because the columns you are trying to extract data from do not exist in the Cursor (the getColumnIndex method returns -1 if the column cannot be found).
The Cursor will only have a single column named MAX(reps).
You can easily add all the other columns by adding * (separated from the MAX(reps) column by a comma or you could add other columns individually as elements of the array. If you want to display the maximum reps you would extract the column named MAX(reps) or you could rename the column using AS e.g. MAX(reps) as maxreps
So you could have :-
private Cursor getRepRecord(String excersise) {
return myDatabase.query(Contact.ExcersiseEntry.TABLE_NAME,
new String [] {"MAX(reps) AS maxreps", *}, //<<<< Changed
Contact.ExcersiseEntry.EXCERSISE_NAME + " = '" + excersise + "'",
null,
null,
null,
Contact.ExcersiseEntry.EXCERSISE_REPS + " DESC");
}
This could be used in conjunction with a slightly amended getEntryFromDatabase method :-
private void getEntryFromDatabase(Cursor cursor) {
//cursor.moveToFirst(); //<<< does nothing of any use as return value is ignored
while (!cursor.isAfterLast()) {
String excersise = cursor.getString(cursor.getColumnIndex(Contact.ExcersiseEntry.EXCERSISE_NAME));
int reps = cursor.getInt(cursor.getColumnIndex(Contact.ExcersiseEntry.EXCERSISE_REPS)); // Would this be of any use???
int id = cursor.getInt(cursor.getColumnIndex(Contact.ExcersiseEntry._ID));
int maxreps = cursor.getInt(cursor.getColumnIndex("maxreps")); //<<<< Added
Log.i("Entry", "ID: " +id + " || Excersise: " + excersise + " || reps: " + Integer.toString(reps) + " || maxreps: " + Integer.toString(maxreps);
cursor.moveToNext();
}
}
EDIT re comment :-
I still don´t quite understand why. The correct SQL term would be
something like SELECT * WHERE reps = max(reps), right? How does it
translate into the Max(reps), *
If you used SELECT * FROM reps WHERE reps = Max(reps) it would return all defined columns (the * translates to all columns) for the row or rows that is/are equal to highest rep value (note see below why this would work anyway). Which could be what you want. (ORDER BY reps DESC (or ASC) is irrelevant).
The list of columns after SELECT (SELECT ALL or SELECT DISTINCT) defined the result_columns i.e. the columns that will exist in the resultant Cursor. If you said SELECT reps FROM reps then the resultant cursor would have just the 1 column called reps. SELECT reps, exercise then the resultant cursor would have two columns.
SQL allows derived columns (my term). The derived column name will take the name of the expression used to derive the value. So if you say SELECT max(reps) FROM reps then the result will be a Cursor with 1 column named max(reps) (and because MAX is an aggregate function 1 row (unless GROUP BY is used)).
The query method used (there are 4 in total) in your code has the signature :-
Cursor query (String table,
String[] columns, //<<<< list of result columns
String selection, //<<<< WHERE CLAUSE
String[] selectionArgs,
String groupBy,
String having,
String orderBy)
So :-
myDatabase.query(Contact.ExcersiseEntry.TABLE_NAME,
new String [] {"MAX(reps)"},
Contact.ExcersiseEntry.EXCERSISE_NAME + "= '" + excersise + "'",
null,
null,
null,
Contact.ExcersiseEntry.EXCERSISE_REPS + " DESC");
results in the SQL SELECT MAX(reps) FROM reps WHERE excercise = 'your_excercise';
So the resultant Cursor will have 1 column named MAX(reps).
If you wanted SELECT * FROM reps WHERE reps = MAX(reps) then you'd use :-
myDatabase.query(Contact.ExcersiseEntry.TABLE_NAME,
null, //<<<< ALL columns
Contact.ExcersiseEntry.EXCERSISE_REPS + " = MAX(reps)",
null,
null,
null,
Contact.ExcersiseEntry.EXCERSISE_REPS + " DESC" // Irrelevant
);
However, this would be for all Exercises and could thus return multiple rows BUT it would be a misuse of an aggregate function (attempt apply the function on a per row basis as opposed to on a per group basis (all rows are the group as no GROUP BY has been specified)).
You'd have to use a subquery e.g. SELECT * FROM reps WHERE reps = (SELECT MAX(reps) FROM reps)
I'm having a lot of trouble with checking if a cursor contains any results.
I have a method that "removes" all rows from a given table which is here:
Chevron.class
public void deleteAllRecords(){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME,null,null);
}
I then call a method which adds the SUM of the first row of the database which is here:
public Cursor getRecalculate(){
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select SUM (" + SECOND_FIELD + ") FROM " + TABLE_NAME, null);
return res;
}
My major issue is that if I remove all records from the database, res.getCount() still equals 1 but contains no information but then the method only returns 1 row anyway. So I'm stuck with how to check if the cursor has actual table data or just empty table data.
I've tried stuff like
if(res.getString(0) == null){
.. Do code
}
but that doesn't work.
I get the error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ceri.twostep_onecheck/com.example.ceri.twostep_onecheck.ShowGraph}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
If you want to know how many rows there are that match your query constraints, add COUNT(*) to the SELECT statement:
SELECT COUNT(*), SUM(whatever) FROM other_thing;
Then, move the Cursor to the first row via moveToFirst(), and examine the two values (getInt(0) for the count and getInt(1) for the sum).
Use getReadableDatabase() instead of getWritableDatabase().
Try this:
public Cursor getRecalculate() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("select SUM (" + SECOND_FIELD + ") FROM " + TABLE_NAME, null);
return res;
}
Read cursor value:
// Move the cursor to the first row if cursor is not empty
if(res.moveToFirst())
{
do
{
// Do something with cursor
}while(res.moveToNext()); // Move cursor to next row until it pass last entry
}
// Close
res.close();
Hope this will help~
Try this
cursor.getCount();
This should return at least one if cursor reads something or it will return zero.
I am trying to get the last 3 entries made to the database. Im using the following code but im only getting the last entry not the last 3.
String query = "Select * from " + TABLE_DETAILS + " DESC limit 3;";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
cursor.moveToFirst();
System.out.println(Integer.parseInt(cursor.getString(2)));
cursor.close();
} else {
}
db.close();
Thanks
You'll need to loop with the cursor to get all result rows, e.g. instead of
if (cursor.moveToFirst()) {
...
loop like this
while (cursor.moveToNext()) {
System.out.println(cursor.getString(2));
}
cursor.close();
To change the ordering, add ORDER BY <expression> to your query, for example
SELECT ... ORDER BY _id DESC LIMIT 3
I have a table with this info:
i create table.
db.execSQL("CREATE TABLE IF NOT EXISTS income (id_income INTEGER
PRIMARY KEY AUTOINCREMENT, id_category INT(20), id_account INT(20),
Year INT(5), month INT(5), day INT(5) ,pay DOUBLE(20));");
then i insert a row in this table:
db.execSQL("INSERT INTO
income(id_category,id_account,Year,month,day,pay) VALUES
(1,1,2013,1,1,678);");
Then i select * from my table,
String selectQuery = "SELECT * FROM income ";
Cursor cursor = db.rawQuery(selectQuery, null);
cursor.moveToFirst();
int count = cursor.getCount();
if(count>0){
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
int temp_acc1;
int temp_cat;
temp_acc1=(cursor1.getColumnIndex("id_account"));
temp_cat=(cursor1.getColumnIndex("id_category"));
}
}
But when i log temp_acc1 or temp_cat, it returns number of column.
For example temp_acc1 returns 3 // actually returns 1
or temp_cat returns 2 // actually returns 1
or if i use temp_year=cursor1.getColumnIndex("Year") it returns 5.//// actually returns 2013
What should i do?
Please help me.
Change this kind of codecursor1.getColumnIndex("Year") to this cursor1.getInteger(cursor1.getColumnIndex("Year")). So it will return the value
This is what i am using for insert:
public long insert(String content, Date startAt, Date endAt) {
if (content == null || startAt == null) {
return 0;
}
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_CONTENT, content);
contentValues.put(KEY_START_AT, startAt.getTime());
if (endAt == null) {
contentValues.putNull(KEY_END_AT);
} else {
contentValues.put(KEY_END_AT, endAt.getTime());
}
return sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
}
now i want to create update method which will update last inserted row. How can i get last inserted row?
If you have an id attribute that works as a primary key, you can do a raw database query on SqlLite.
Cursor cc = this.mDb.rawQuery("SELECT *" + " FROM " + "<Your DATABASE_NAME> " +
"ORDER BY id " + "DESC LIMIT 1", null);
return cc;
Here,
1. It returns a cursor.
2. mDb is a SQLiteDatabase class instance.
3. ORDER BY id allows the query to sort by id number. As I said, if you have an id as primary key in your table, your latest entry will have the maximum id number.
4. DESC allows to sort by descending order.
5. LIMIT 1 allows to return only 1 row.
6. Always be careful when writing raw queries, white spaces inside the query can be a lot of pain when you do not handle them carefully.
For further queries you can see this tutorial. And obviously Divya's answer is also a good one.
You can use a cursor to retrieve rows and say :
cursor.moveToLast();
OR
cursor.moveToPosition(cursor.getCount() - 1);
When you insert a row in to your table the insert query returns the key of the last inserted row. You can now use this key to update this row.
for example
int newInsertedKey = sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
update table_name set column_name = 'Change 2' where columnID = newInsertedKey
An efficient method would be to avoid anymore database queries to get the last updated row.
Maybe he should use something like this
public long getLastId() {
Cursor c = mDb.query(currentTableName, new String[] { "MAX(_id)" },
null, null, null, null, null, null);
try{
c.moveToFirst();
long id = c.getLong(0);
return id;
}catch(Exception e){
return 0;
}
}
where _id is column by which you identify rows