Application crashes while reading an empty table in android - android

The issue is purely with the contents inside the tables. If the table is not empty (with one or more records), application works perfectly. I am deleting the contents of table and immediately after that reading the same table, it throws exception and app force closes.
I tried searching for it but couldn't conclude. The key point is : index out of bound exception which is thrown at movetofirst() method of cursor when i am going to read the table, i suppose... Please help.
public List<TableData> readForPaymentDetais()
{
List<TableData> paymentDetails = new ArrayList<TableData>();
try
{
String selectQuery = "select * from PaymentDetails";
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
if(cursor.getCount() !=0)
{
if(cursor.moveToFirst())
{
do
{
TableData data = new TableData();
data.setPaymentMade(Float.valueOf(cursor.getString(0).toString()));
data.setDateOfPayment(cursor.getString(1));
paymentDetails.add(data);
}
while(cursor.moveToNext());
}
}
return paymentDetails;
}
catch(Exception exc)
{
return null;
}
}

Before executing moveToFirst method of cursor please check whether cursor is empty. For that you can use code like:
if (mCursor.getCount() == 0) {
// cursor is empty
}
If cursor is not empty put your stuff in else part.

Related

my sqlite cursor returns empty result for a query

I have a small function for checking to see if a records already exists in my sqlite database. There is data in the database that should match the query, i have verified this by opening up the database.But i get an empty result.
Below is the function, it takes in a parameter and uses that as the search parameter. i have also verified that the parameter is correct.
public boolean checkParent(String email)
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = null;
try
{
res = db.rawQuery("SELECT * FROM parents WHERE email = ' " + email + " ' ",null);
res.close();
}
catch (Exception ex)
{
Log.e("Error checking parent", ex.toString());
}
if(res == null)
{
return true;
}
else
{
return false;
}
}
Right way to pass argument in rawQuery method.
db.rawQuery("SELECT * FROM parents WHERE email = ?",new String[]{email});
You are checking whether the cursor object res is null. This will never happen; rawQuery() always returns a cursor object.
You have to check whether the cursor is empty, i.e., whether the cursor actually contains any rows. To do this, call a method like moveToFirst() and check if it succeeds.
Or even better, use a helper function that does handle the cursor for you:
public boolean checkParent(String email)
{
SQLiteDatabase db = this.getReadableDatabase();
long count = DatabaseUtils.queryNumEntries(db,
"parents", "email = ?", new String[]{ email });
return count > 0;
}

SQLite Database query function not replacing the ? with selection args

i have a get function in my database class to get a specific line from the DB.
public Line getLine(String date){
SQLiteDatabase sql = db.getWritableDatabase();
Cursor cursor;
Line line = new Line();
try{
cursor = sql.query(Db_name,null,DATE_COL+"=?",new String[] {date},null,null,null);
line = new Line(cursor.getInt(0),cursor.getString(1),cursor.getString(2),cursor.getString(3).equals("YES"));
}
catch (Exception e){
e.getCause();
}
finally {
if (sql.isOpen())
sql.close();
}
return line;
}`
however when i run it, the cursor is not getting the right query, when debbuging it looks like this:
SQLiteQuery: SELECT * FROM a28a9a2015 WHERE date_col=?
so it kept the ? and did not put the date string in there..
i've tried something like -
cursor = sql.query(Db_name,null,DATE_COL+"="+date,null,null,null,null);
OR
cursor = sql.query(Db_name,null,DATE_COL+"= '"+date+"',null,null,null,null);
with same result.
any pointers?
You need to move cursor to first position
cursor = sql.query(Db_name,null,DATE_COL+"=?",new String[] {date},null,null,null);
if (cursor.moveToFirst()) {
// TODO
}
Otherwise your cursor is in position -1 and cannot get any data. Symbol "?" is replacing inside request to sqlite so in cursor you'll see "?".

Using WHERE Clause SQLite database in Android?

This is my code:
public int getIdMotChuDe(String tenChuDe) {
int IDChuDe = 0;
try
{
Cursor c = null;
c = database.rawQuery(
"SELECT ChuDeID FROM DanhSachChuDe WHERE TenChuDe = ?"
, new String[] {tenChuDe});
c.moveToFirst();
IDChuDe = c.getInt(c.getColumnIndex("ChuDeID"));
c.close();
}
catch(Exception e)
{
e.printStackTrace();
}
return IDChuDe;
}
I'm trying to get ChuDeID from DanhSachChuDe table with condition in WHERE clause. But i don't know why this function always return 0.
Help me please. Thanks! Sorry because my english.
This could be because an Exception is being thrown. The code you are using is not correctly checking the state of your Cursor - it attempts to moveToFirst() before any checking too see if the object is not null.
Your code also assumes a result is always returned. This is bad practise, and should be avoided. A much safer and more common solution is the following:
if (cursor != null) {
// If the cursor has results, move the cursor to first row
if (cursor.moveToFirst()) {
do {
// YOUR METHODS HERE
// then move to next row
} while (cursor.moveToNext());
}
}

Android SQLite checking if tables contain rows

So I'm working on a game for android and I'm currently stuck at the 'load savegame' button in the main menu.
This button calls methods that read data from the database and write it into a resource class from which on this data will be accessed.
The problem is: I want to disable the load button if there are no rows in the tables, which means that no savegame exists.
To do this I used the following method:
public boolean checkForTables(){
boolean hasTables;
String[] column = new String[1];
column[0] = "Position";
Cursor cursor;
cursor = db.query("itemtable", column, null, null, null, null, null);
if(cursor.isNull(0) == true){
hasTables=false;
}else{
hasTables=true;
}
return hasTables;
As you can see it starts a query on one of the database tables and checks if the 0-column, which is the only one that should be in this cursor, is null. ATM I can't check logcat results on this call because I seem to have some problems with it, but it seems that the query throws an exception because the table is empty.
Any idea to check the tables for rows?
____________________EDIT______________
NOTE: I checked the database and it sure is empty
Okay I used a rawQuery on the table but the approach with count-statement produced an error, so I'm using
public boolean checkForTables(){
boolean hasTables;
Cursor cursor = db.rawQuery("SELECT * FROM playertable", null);
if(cursor.getCount() == 0){
hasTables=false;
if(cursor.getCount() > 0){
hasTables=true;
}
cursor.close();
return hasTables;
}
I'm using this method to decide whether or not to disable the loadGame-button which looks like this:
loadGame = (ImageButton) findViewById(R.id.loadButton);
loadGame.setEnabled(databaseAccess.checkForTables());
loadGame.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
databaseAccess.loadPlayer();
databaseAccess.loadItems();
databaseAccess.dropTables();
}
});
So if checkForTables gets a rowcount of != 0 it will return true and therefore enable the Button, or disable it if rowcount = 0
Amusingly, although the tables are empty, checkForTables() returns true because getCount() seems to return a != 0 value - I just don't get it.
Perform a query such as select count(*) from itemtable. This query will yield you a single integer result, containing the number of rows in that table.
For example:
Cursor cursor = db.rawQuery("SELECT count(*) FROM itemtable");
if (cursor.getInt(0) > 0) ... // there are rows in the table
-------------------------------------------------------------------------------------
Please note that the following edit was attempted by #PareshDudhat but was rejected by reviewers. I have not kept up with Android since this answer was posted, but a very brief bit of research suggests the edit (at least the change to how rawQuery() is called, I didn't inspect the moveToFirst() but #k2col's comment suggests it is required now as well) has merit.
Cursor cursor = db.rawQuery("SELECT count(*) FROM itemtable",null);
cursor.moveToFirst();
if (cursor.getInt(0) > 0) ... // there are rows in the table
What mah says will work. Another approach you could use in your current function is:
hasTables = cursor.moveToFirst());
Note that this approach is probably only better to use if you plan on using the results of the query if hasTables is in fact true.
Also, don't forget to close your cursor when you are done with it!
EDIT
I don't know if this is your problem but in your edit you are querying for all items from the playerTable instead of the itemTable as you did in the pre-edit. Is that your problem?
cursor.getCount()
return the number of rows in database table.
and then try
Toast.makeText(this,""+cursor.getCount(),Toast.LENGTHLONG).show();
and it will give you no of rows in database table
The accepted answer put me on the right track, but didn't compile because rawQuery's method signature has changed and the cursor wasn't advanced to the first row before being read.
Here's my solution which includes error handling and closes the cursor:
public static boolean isEmpty() {
boolean isEmpty;
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT count(*) FROM itemtable", null);
if (cursor.moveToFirst()) {
isEmpty = cursor.getInt(0) == 0;
} else {
// Error handling here
}
} catch (SQLException e) {
// Error handling here
} finally {
cursor.close();
}
return isEmpty;
}

Get updated rows count from SQLite in Android using a raw query?

How can I get the number of rows updated using an update statement in SQLite in Android?
Note that I need to use some type of raw execute of a SQL statement, rather than do anything with ContentValues because I need a dynamic query. Thus I can't make use of the SQLiteDatabase.update() method. For example, I'm running something like
UPDATE my_table
SET field_name = field_name + 1
The methods I know of return void, e.g. SQLiteDatabase.execSQL(). SQLiteDatabase.rawQuery() returns a Cursor, but the cursor has zero rows and its count is always -1.
You could do your insert whichever way you want, and then do a select and use the changes() function to return the number of affected rows.
To expand on Mat's answer, here's the example code for getting the updated row count:
Cursor cursor = null;
try
{
cursor = db.rawQuery("SELECT changes() AS affected_row_count", null);
if(cursor != null && cursor.getCount() > 0 && cursor.moveToFirst())
{
final long affectedRowCount = cursor.getLong(cursor.getColumnIndex("affected_row_count"));
Log.d("LOG", "affectedRowCount = " + affectedRowCount);
}
else
{
// Some error occurred?
}
}
catch(SQLException e)
{
// Handle exception here.
}
finally
{
if(cursor != null)
{
cursor.close();
}
}
Expanding on Mat and Pang's answers...
Could we skip the Cursor and use simpleQueryForLong()?
e.g.
public long getChangesCount() {
SQLiteDatabase db = getReadableDatabase();
SQLiteStatement statement = db.compileStatement("SELECT changes()");
return statement.simpleQueryForLong();
}
You can use SQLiteStatement.executeUpdateDelete method for this:
SQLiteDatabase db = getReadableDatabase();
SQLiteStatement statement = db.compileStatement("[your sql here]");
int affectedRows = statement.executeUpdateDelete();
The same method used internally in SQLiteDatabase.update(...) methods.

Categories

Resources