Cursor returning 0 - android

I have a function where I want to get the sum of values on a MySQL database table's row. This is my code:
public int getSum(int var) {
int x=0;
// Select All Query
String selectQuery = "SELECT sum(amount) FROM donations WHERE aid = '"+aid+"'";
SQLiteDatabase db = openOrCreateDatabase("shareity", Context.MODE_PRIVATE, null);
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
x = cursor.getInt(0);
} while (cursor.moveToNext());
}
// return contact list
Log.d("id", "Id" + "," + x);
return x;
}
And I'm calling this in the onCreate() like this:
getSum(idk);
where idk is an integer. But my this returns 0. Can I know why please? The table's row I want to get the sum of, is also integer.

Finally figured it out. The problem was with the SQLite database. I had to use a php file to download the database from the mysql server to the local Sqlite server and then loop through it

Related

java.lang.IllegalStateException: Couldn't read row 0, col 10 from CursorWindow

Please check following code:
List<Database> zaznamy = new ArrayList<Database>();
String selectQuery = "SELECT X FROM Data WHERE LEVEL_1 =-24 AND LEVEL_2 =-48 AND LEVEL_3 =-55 AND LEVEL_4 =0";
File dbfile = new File("/sdcard/rtls/Databases/"+DBName );
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
Cursor cursor = db.rawQuery(selectQuery,null);
String bodX="empty";
if (cursor.moveToFirst())
{
do {
Database zaznam = new Database();
zaznam.setX(Integer.parseInt(cursor.getString(10)));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
for (Database cn : zaznamy)
{
Log.d("X: ", Integer.toString(cn.getX()));
bodX = (cn.getX()+ "//").toString();
Log.d("X", bodX);
}
}
It says it Couldn't read row 0, col 10 from CursorWindow. I´ve tested the database with SQLite browser. Database has exactly 1 X at column 10, row 0. SQL query is working correctly I believe. Can someone tell me, why it cant be read? Or where is mistake?
EDIT:
corrected the code to:
do {
Database zaznam = new Database();
zaznam.setX(cursor.getInt(10));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
because of integer value of 10th column, but still no luck. Same error
Your query has only one column in projection - column 'X'. That column has index 0 in query projection so to make your code work change your loop to looks like this:
do {
Database zaznam = new Database();
zaznam.setX(cursor.getInt(0));
zaznamy.add(zaznam);
} while (cursor.moveToNext());
To avoid that kind of problems in the future use following:
cursor.getInt(cursor.getColumnIndexOrThrow("X");
Remember that column index is related to query projection and not the sequence of columns in your database, so for example when you write "select B A C from SOME_TABLE" column B will have index 0 and column A will have index 1 etc. even if in your database they are in alphabetical order A B C.
I was having the same issue. For me. A simple work around may be:
// query database and populate an ArrayList
private void getDataFromDatabase() {
Cursor cursor = dbConnector.getSomeData();
if (cursor.getCount() > 0) {
cursor.moveToFirst();
for(int i = 0; i < cursor.getCount(); i++) {
// get column data from database and add it to ArrayList
anArrayList.add(cursor.getString(cursor.getColumnIndexOrThrow("Attr")));
cursor.moveToNext();
} // end for
} // end if
dbConnector.close();
} // end getDataFromDatabase
WHERE "Attr" is the Attribute/column name you wish to query and the anArrayList is the ArrayList you want to store the data in.

Android SQLITE Query: Getting last 3 entries

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

Fastest way to search through strings stored in sqlite database

I have large number of strings, approximately 15,000 that I stored in a SQLite database using the following code:
void addKey(String key, String value, String table) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_KEY, key); // Contact Name
values.put(KEY_VALUE, value); // Contact Phone
// Inserting Row
db.insert(table, null, values);
db.close(); // Closing database connection
}
And then i search through that database using the following method in order to pick out any strings that match the key im looking for:
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
if(cursor.getString(1).equals(key))
rtn = rtn + "," + cursor.getString(2);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
The goal is to do this in real time as the user is typing on the keep board so response time is key and the way it stands now it takes over a second to run through the search.
I considered reading all of the items into an array list initially and sorting through that which might be faster, but i thought an array list of that size might cause memory issues. What is the best way to search through these entries in my database?
A couple of things you can do...
Change the return to a StringBuilder until the end.
Only use a readable version of the database (that's probably not making much difference though)
Do not get a new instance of the database every time, keep it opened until you don't need it anymore
Query for only what you need with the "WHERE" argument in the SQL query.
See the code below with some changes:
// move this somewhere else in your Activity or such
SQLiteDatabase db = this.getReadableDatabase();
public String searchKeyString(String key, String table){
StringBuilder rtn = new StringBuilder();
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + " WHERE KEY_KEY=?";
Cursor cursor = db.rawQuery(selectQuery, new String[] {key});
// you can change it to
// db.rawQuery("SELECT * FROM "+table+" WHERE KEY_KEY LIKE ?", new String[] {key+"%"});
// if you want to get everything starting with that key value
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Log.d("searchKeyString","searching");
rtn.append(",").append(cursor.getString(2));
} while (cursor.moveToNext());
}
cursor.close();
Log.d("searchKeyString","finish search");
return rtn.toString();
}
Note even if you want this to happen in "real-time" for the user, you will still need to move this to a separate Thread or ASyncTask or you are going to run into problems....
You should consider using SELECT * FROM your-table LIMIT 50, for example. And you can put two buttons "Back", "Next" on your view. If every page has max 50 items, the user is at page 1, and he taps "Next", then you can use this query:
SELECT * FROM your-table LIMIT 50 OFFSET 50
If your table contains most of text-data, and you want to integrate search deeply into your app, consider using virtual table with FTS.
Let sqlite do the hard lifting.
First off, add an index to the field you're searching for, if you don't have one already. Secondly, don't do a SELECT all with manual table scan, but rather use a query in the form
SELECT column_value
FROM my_table
WHERE column_key LIKE "ABC%"
This returns the least amount of data, and the sql engine uses the index.
i dunno about better but maybe it'd be faster to make queries for the selected strings one by one.
public String searchKeyString(String key, String table){
String rtn = "";
Log.d("searchKeyString",table);
// Select All Query
String selectQuery = "SELECT * FROM " + table + "WHERE column_1 = " + key;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
rtn = rtn + "," + cursor.getString(2);
}
cursor.close();
db.close();
Log.d("searchKeyString","finish search");
return rtn;
}
EDIT:
Well i dunno how those custom keyboard apps do it, but those AutoCompleteTextViews are hooked up to adapters. you could just as easily make a cursorAdapter and hook your auto-complete view to it.
http://www.outofwhatbox.com/blog/2010/11/android-autocompletetextview-sqlite-and-dependent-fields/
http://www.opgenorth.net/blog/2011/09/06/using-autocompletetextview-and-simplecursoradapter-2/

SQLite: How to get average of long type values

I'm making an app that records the timestamp of touchscreen actions made my the user.
Then, after recording the readings in an SQLite table, I take the average of each column at the end. However, I'm getting an error:
E/AndroidRuntime(1344): java.lang.NumberFormatException: Invalid long: "1.40024e+08"
This happens when I try to take the average of each column, which I'm doing like so:
public long[] getAvg()
{
String selectQuery = "SELECT AVG(dwell_1), AVG(dwell_2), AVG(dwell_3), AVG(dwell_4), AVG(dwell_5), AVG(dwell_6), AVG(dwell_7), AVG(dwell_8), AVG(dwell_9), AVG(flight_12), AVG(flight_23), AVG(flight_34), AVG(flight_45), AVG(flight_56), AVG(flight_67), AVG(flight_78), AVG(flight_89) FROM " + TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
long[] row = new long[17];
if (cursor.moveToFirst()) {
for (int j=0; j<17; j++)
row[j] = Long.parseLong(cursor.getString(j));
}
return row;
}
It seems to be a function of the way the SQLite query displays the results. Is there any way I can circumvent/solve this? I require the precision by the way, so I can't use int or something else instead.
Oddly enough, when I run a query to just straight up display every record in the table, it works fine.
Any help will be greatly appreciated. Thanks in advance!
I believe SQLiteAVG() function returns a float value which you are trying to parse it as Long, hence the exception.
Try this :
public long[] getAvg()
{
String selectQuery = "SELECT AVG(dwell_1), AVG(dwell_2), AVG(dwell_3), AVG(dwell_4), AVG(dwell_5), AVG(dwell_6), AVG(dwell_7), AVG(dwell_8), AVG(dwell_9), AVG(flight_12), AVG(flight_23), AVG(flight_34), AVG(flight_45), AVG(flight_56), AVG(flight_67), AVG(flight_78), AVG(flight_89) FROM " + TABLE;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
long[] row = new long[17];
if (cursor.moveToFirst()) {
for (int j=0; j<17; j++)
row[j] = cursor.getLong(j);
}
return row;
}
SQLite returns float result, which you are trying to save to long.
Possible solutions:
Use float/double variables on Java side.
Or force SQLite to output integer/long using
SELECT CAST(avg(field) AS INTEGER) AS avg_field...
In your case, result should still fit into Java long if original was SQLite INTEGER.
Consider a simple method that fetches the average rating of an entity. The rating float value is stored between 0.0 to 5.0.
public static float getAverageReviews(SQLiteDatabase db) {
String selectQuery = "SELECT SUM(stars) * FROM " + DatabaseHelper.TABLE_STORE_REVIEWS;
Cursor c = db.rawQuery(selectQuery, null);
int count = c.getCount();
float totalSum = 0;
if(count > 0 && c.moveToFirst())
{
do {
String result = c.getString(c.getColumnIndex(StoreReviews.KEY_STARS));
totalSum += Float.parseFloat(result);
} while (c.moveToNext());
}
else {
return 0;
}
return totalSum/count;
}

Access a column from database

Now I want to access an entire column from database and then compare it with some text that I have stored...but I am getting no idea on how to do that..So can someone please help me with this...
Entire column? You mean all the values for a given column accross all records?
You should iterate the ResultSet obtained and start comparing the values (for example - if you iterate using "rs" object of ResultSet, you should compare:
String valueFromDB = rs.getString("myColumn");
String someTextStored = .... //the text being stored
if (valueFromDB != null) {
if (someTextStored.equals(valueFromDB) {
//Comparison succeeded - implement some logic here for handling success
}
}
And the above code should be inside a loop code that iterates over the ResultSet and
uses the "next" method to obtain the next record.
Hope this helps you
public ArrayList<String> getValues(){
Cursor cursor = null;
SQLiteDatabase db = getReadableDatabase();
Log.v("done","getting rows ");
cursor = db.rawQuery("SELECT YourColumnName FROM "+TABLE_NAME, null);
if(!cursor.moveToFirst()){
}
else{
do {
list_values.add(cursor.getString(0));
} while (cursor.moveToNext());
}
db.close();
cursor.close();
return list_values;
}
Now you are having all the values of a particular column you can compare it from this array list.

Categories

Resources