Saving SQLite list as an array: Not Working [duplicate] - java

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 7 years ago.
I have an SQLite Database, and within it, one of the columns stores Strings which include numbers. I am trying to retrieve the numbers, store them as doubles in an array, and then take the mean of the array. However, it's not working. The App crashes every time I get to that part. I know the problem has to be somewhere within the array because I am able to list the SQLite Database as a string.
public int getDataCount() {
String countQuery = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE 1";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int cnt = cursor.getCount();
cursor.close();
return cnt;
}
public double databaseAverage(){
String dbString = "";
int dbInt = 0;
double dbDouble = 0;
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE 1";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
int rowCount = getDataCount();
Double[] array = new Double[rowCount];
int i = 0;
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("productname")) != null) {
dbString += c.getString(c.getColumnIndex("productname"));
dbInt = Integer.parseInt(dbString.replaceAll("[\\D]",""));
dbDouble = (double) dbInt;
array[i] = dbDouble;
i++;
}
c.moveToNext();
}
db.close();
double sum = 0;
for(int v=0; v < array.length ; v++) {
sum = sum + array[i];
}
double average = sum / array.length;
return average;
}

please check your syntax :
String query = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE 1";
While it should be :
String query = "SELECT * FROM " + TABLE_PRODUCTS + " WHERE "+ {your coloumn name }+"=1";
Check above query in both methode getDataCount and databaseAverage

Related

Getting SQLite DB data in 2d array and returning in android

I have the below function which I use to query the SQLite Db, put the retrieved records in to an array and return it back.
public String[][] getrecords(){
Log.i("SENDSERVER", "Get Records Called");
SQLiteDatabase sampleDB = this.getReadableDatabase();
Cursor c = sampleDB.rawQuery("SELECT id,welawa,lati,longi FROM " +
TABLE_LOCATIONS + " LIMIT 5", null);
String[][] aryDB = new String[5][4];
int i = 0;
if (c != null ) {
if (c.moveToFirst()) {
do {
String db_id = c.getString(c.getColumnIndex("id"));
String welawa = c.getString(c.getColumnIndex("welawa"));
String latitude = c.getString(c.getColumnIndex("lati"));
String longitude = c.getString(c.getColumnIndex("longi"));
aryDB[i][0] = db_id;
aryDB[i][1] = welawa;
aryDB[i][2] = latitude;
aryDB[i][3] = longitude;
Log.i("SENDSERVER", "Record Added"); //This doesn't get logged
i++;
}while (c.moveToNext());
}
}
Log.i("SENDSERVER", "Return Records");
return aryDB;
}
I try to retrieve the records and use them as below from my service class.
String aryDB[][] = dbh.getrecords();
Log.i("SENDSERVER", "GET DB RECORDS");
int i = 0;
int id = 0;
String welawa = "";
String lati = "";
String longi = "";
while(i < 5){
id = Integer.parseInt(aryDB[i][0]);
welawa = aryDB[i][1];
lati = aryDB[i][2];
longi = aryDB[i][3];
Log.i("SENDSERVERDB", id + " - " + welawa + " - " + lati + " - " + longi);
i++;
}
For some reason the array is not being returned.
My possible guesses are,
1. The defining of the function is wrong. My intention is to return the array.
2. I am getting the db connection / my retrieval code is wrong.
3. Some thing else that my noob brain can't comprehend.
Your help is greatly appreciated guys.
------EDIT
After adding some more logs the app crashes at
Cursor c = sampleDB.rawQuery("SELECT id,welawa,lati,longi FROM " +
TABLE_LOCATIONS + " LIMIT 5", null);
Any issue in my query?
It was a DB issue. Wrong ColumnName used.
The Cursor never returns null when there is no row which the requested conditions, just return a empty Cursor.
You code still has problem when the rawQuery returns 0 rows, cursor won't be null and do while loop will execute at least once.
So there will be problem on this line when the cursor is empty
c.getString(c.getColumnIndex("id"));
Change your code to this:
c.moveToFirst();
while (c.moveToNext())
{
String db_id = c.getString(c.getColumnIndex("id"));
String welawa = c.getString(c.getColumnIndex("welawa"));
String latitude = c.getString(c.getColumnIndex("lati"));
String longitude = c.getString(c.getColumnIndex("longi"));
aryDB[i][0] = db_id;
aryDB[i][1] = welawa;
aryDB[i][2] = latitude;
aryDB[i][3] = longitude;
Log.i("SENDSERVER", "Record Added"); //This doesn't get logged
i++;
}

Getting Exception Index 1 requested, with a size of 1

I am getting exception while fetching data from database in my android project. I am trying to get value of column index 1 from this line of code String ques=c.getString(1);
And this is the code where i am calling database class and trying to fetch database,
try{
c=db.getText(Integer.toString(subid));
if(c==null)
return;
//if(c.getCount()> 0)
//{
//int max=c.getCount();
//int min=0;
Random rn = new Random();
int randomNum = rn.nextInt(max-1) + rowid;
c.moveToPosition(randomNum);
String ques=c.getString(1);
tv.setText(ques+" ");
cans=c.getString(2);
shuffleArray(ans);
int[] a = new int[4];
int j=0;
for (int i = 0; i < ans.length; i++)
{
a[j]=ans[i];
j++;
}
ans1=c.getString(a[0]);
ans2=c.getString(a[1]);
ans3=c.getString(a[2]);
ans4=c.getString(a[3]);
rb1.setText(ans1);
rb2.setText(ans2);
rb3.setText(ans3);
rb4.setText(ans4);
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), e.getMessage()+"exception", Toast.LENGTH_LONG).show();
}
Snap shot of my database content,
this is my database class,
public Cursor getText(String subId) throws SQLException //here it'll get all rows of subId=1 or whatever the value of subId
{
Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {
KEY_id, KEY_ques, KEY_correctans, KEY_wrongans1,KEY_wrongans2, KEY_wrongans3},
KEY_subjectid + "=" + " '" + subId + "' " , null,null,null, null,null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
Please help me and hope my question is clear.
Thanks in Advance.
You have an error:
Index 1 requested, with a size of 1
It says, that the size of your cursor is 1 and you know that indexing starts with 0. Therefore, if you write:
String ques = c.getString(1);
you try to get SECOND element, not the first one. If you want to get first element, you have to write:
String ques = c.getString(0);
Remove c.MovetoPosition(randomno);
Instead try this:
c.moveToFirst();
int rw_cnt=c.getCount();
int rndm = ((Math.random())*10000)%rw_cnt); //generates a random no btwn 1 and rw_cnt
for(int i=0;i<rndm;i++) //move cursor rand times
c.moveToNext();
This definitely would be slower than c.moveToPostion(); but it wouldn't make much of a difference unless you have thousands of rows

Getting Exception Index 50 requested, with a size of 50

I am getting exception while fetching data from database. I am trying to get value of column index 1 from this line of code String ques=c.getString(1);
this is the code where i am calling database class and trying to fetch database,
try{
c=db.getText(Integer.toString(subid));
if(c==null)
return;
//if(c.getCount()> 0)
//{
//int max=c.getCount();
//int min=0;
Random rn = new Random();
int randomNum = rn.nextInt(max-1) + rowid;
c.moveToPosition(randomNum);
String ques=c.getString(1);
tv.setText(ques+" ");
cans=c.getString(2);
shuffleArray(ans);
int[] a = new int[4];
int j=0;
for (int i = 0; i < ans.length; i++)
{
a[j]=ans[i];
j++;
}
ans1=c.getString(a[0]);
ans2=c.getString(a[1]);
ans3=c.getString(a[2]);
ans4=c.getString(a[3]);
rb1.setText(ans1);
rb2.setText(ans2);
rb3.setText(ans3);
rb4.setText(ans4);
}
catch(Exception e)
{
Toast.makeText(getApplicationContext(), e.getMessage()+"exception", Toast.LENGTH_LONG).show();
}
Snap shot of my database content,
And this is my database class,
public Cursor getText(String subId) throws SQLException //here it'll get all rows of subId=1 or whatever the value of subId
{
Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {
KEY_id, KEY_ques, KEY_correctans, KEY_wrongans1,KEY_wrongans2, KEY_wrongans3},
KEY_subjectid + "=" + " '" + subId + "' " , null,null,null, null,null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
As my above details and code, When the value of subId is 1 then it is fetching all the content from the database of subId 1 without any Exception but when i am passing the value of subId=2 then it give CursorIndexOutOfBound: Index 50 requested, with a size of 50 Exception
And when i am passing subId=3 then i am getting Index 49 requested, with a size of 49
Is there any problem in Random number generator or what ?
Actually i am not able to get whats the problem here.
I need help.
Thanks in Advance.
Use space in query " = " actually your column name become "KEY_subjectid=" which is wrong
KEY_subjectid + " =" + " '" + subId + "' " , null,null,null, null,null);
Try generating your random number this way: (I'm assuming c is a Cursor)
int randomNum = rowid + (rn.nextInt() % (c.getCount() - rowid));
Hope this helps :)

If + try - catch in method not working properly

I'm working on an SQLite based app. Everything is working fine, except my if-else statements in my method. The saving and stuff works, just the checking is giving me a pretty high blood pressure. I'm hoping one of you is much smarter than i am and finds the probably obvious mistake i made:
public void save() {
// get length of EditText
int dateLength, mileageLength, amountLength, lpriceLength, tpriceLength;
dateLength = date_widget.getText().length();
mileageLength = mileage_widget.getText().length();
amountLength = amount_widget.getText().length();
lpriceLength = price_widget.getText().length();
tpriceLength = totalPrice_widget.getText().length();
// Start save method if EditTexts are not empty.
if (dateLength > 0 || mileageLength > 0 || amountLength > 0
|| lpriceLength > 0 || tpriceLength > 0) {
// Get the value of each EditText and write it into the
// String/doubles
String date = date_widget.getText().toString();
double mileage = Double
.valueOf(mileage_widget.getText().toString());
double amount = Double.valueOf(amount_widget.getText().toString());
double lprice = Double.valueOf(price_widget.getText().toString());
double tprice = Double.valueOf(totalPrice_widget.getText()
.toString());
// Check if mileage is increasing, else cancel and show toast
int checkMileage = Integer.parseInt(db
.getSearchResult("mileage", 0));
if (checkMileage < mileage) {
try {
// if (id == null) {
db.insert(date, mileage, amount, lprice, tprice);
Toast.makeText(this, R.string.action_input_saved,
Toast.LENGTH_SHORT).show();
finish();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "ERROR " + e, Toast.LENGTH_LONG)
.show();
}
} else {
Toast.makeText(
this,
"Your current mileage must be more than the last saved mileage",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "finish your input", Toast.LENGTH_LONG).show();
}
}
My Method in the DbAdapter class:
public String getSearchResult(String sql, int cmd) {
if (cmd == 0) {
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
cursor.moveToFirst();
String tmp = cursor.getString(0);
cursor.close();
// return count
return tmp;
} else if (cmd == 1) {
int sum = 0;
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME;
String idQuery = "SELECT _id FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
Cursor id = db.rawQuery(idQuery, null);
// berechnung
cursor.moveToFirst();
id.moveToFirst();
int maxId = Integer.parseInt(id.getString(0));
for (int i = 0; i < maxId; i++) {
int tmp = Integer.parseInt(cursor.getString(0));
sum = sum + tmp;
cursor.moveToNext();
}
cursor.close();
id.close();
return String.valueOf(sum);
} else if (cmd == 2 && sql == "mileage") {
int sum = 0;
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME;
String idQuery = "SELECT _id FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
Cursor id = db.rawQuery(idQuery, null);
// berechnung
cursor.moveToFirst();
id.moveToFirst();
int maxId = Integer.parseInt(id.getString(0));
if (maxId > 1) {
int array[] = new int[maxId];
// Array füllen
for (int i = 0; i < maxId; i++) {
array[i] = Integer.parseInt(cursor.getString(0));
// sum = sum + tmp;
cursor.moveToNext();
}
for (int k = 1; k < maxId; k++) {
int tmp;
tmp = array[k] - array[k - 1];
sum = sum + tmp;
}
cursor.close();
id.close();
return String.valueOf(sum);
} else {
return "--";
}
}
return "Wrong CMD";
}
I is pretty messy, i know
Turning comment into an answer:
Switch all || to && in your first if. Otherwise you will try to process everything even if only one field is filled in.

Fetching double value from Database and calculate with them

I got another weird problem which i just don't understand.
I am saving doubles into my database with max. 3 digits after the decimal point.
The doubles are stored in the database correctly but when i am trying to fetch the data and add/multiply the stored doubles i get a weird problem
If i am storing data with only one digit after the decimal point, everything works fine and i get the right results.
But if i am adding 2 or more digits after the decimal point my whole calculations won't work. I get no results into my TextViews.
I'm trying to understand whats happening for hours now but i just don't see why this happens.
Here is the code:
My MainActivity, where the TextViews get the Text:
public void calc() {
// Get text for the statistics
amount_widget.setText(db.getSearchResult("amount", 0));
lpayment_widget.setText(db.getSearchResult("price", 0));
tpayment_widget.setText(db.getSearchResult("total_price", 1));
mileage_widget.setText(db.getSearchResult("mileage", 2));
trefueled_widget.setText(db.getSearchResult("amount", 1));
// Calculate text for the consumption
double consumption = (Double.parseDouble(db
.getSearchResult("amount", 1)) / Double.parseDouble(db
.getSearchResult("mileage", 2))) * 100;
consumption = Math.round(consumption * 100) / 100.0;
consumption_widget.setText(consumption + "L /100km");
}
My Database Activity where the code is being fetched and calculated:
public String getSearchResult(String sql, int cmd) {
if (cmd == 0) {
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
String tmp = cursor.moveToFirst() ? cursor.getString(0) : "0";
cursor.close();
return tmp;
} else if (cmd == 1) {
double sum = 0;
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME;
String idQuery = "SELECT _id FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
Cursor id = db.rawQuery(idQuery, null);
// berechnung
cursor.moveToFirst();
id.moveToFirst();
int maxId = Integer.parseInt(id.getString(0));
for (int i = 0; i < maxId; i++) {
double tmp = Integer.parseInt(cursor.getString(0));
sum = sum + tmp;
cursor.moveToNext();
}
cursor.close();
id.close();
return String.valueOf(sum);
} else if (cmd == 2 && sql == "mileage") {
double sum = 0;
String countQuery = "SELECT " + sql + " FROM " + TABLE_NAME;
String idQuery = "SELECT _id FROM " + TABLE_NAME
+ " WHERE _id = (SELECT max(_id) FROM " + TABLE_NAME + ")";
Cursor cursor = db.rawQuery(countQuery, null);
Cursor id = db.rawQuery(idQuery, null);
// berechnung
cursor.moveToFirst();
id.moveToFirst();
int maxId = Integer.parseInt(id.getString(0));
if (maxId > 1) {
int array[] = new int[maxId];
// Array füllen
for (int i = 0; i < maxId; i++) {
array[i] = Integer.parseInt(cursor.getString(0));
// sum = sum + tmp;
cursor.moveToNext();
}
for (int k = 1; k < maxId; k++) {
double tmp;
tmp = array[k] - array[k - 1];
sum = sum + tmp;
}
cursor.close();
id.close();
return String.valueOf(sum);
} else {
return "--";
}
}
return "Wrong CMD";
}
Maybe you're making a simple mistake. Instead of:
consumption_widget.setText(consumption + "L /100km");
try this:
consumption_widget.setText(String.valueOf(consumption) + "L /100km");
I found my mistake.
In my DbAdapter class within the getSearchResult() method i have the following statement:
for (int i = 0; i < maxId; i++) {
double tmp = Integer.parseInt(cursor.getString(0));
sum = sum + tmp;
cursor.moveToNext();
}
Here I am trying to parse an Integer but write it into a double. This is why the calculations couldn't be executed. I need to parse a double like this:
for (int i = 0; i < maxId; i++) {
double tmp = Double.parseDouble(cursor.getString(0));
sum = sum + tmp;
cursor.moveToNext();
}
this is the solution to my problem

Categories

Resources