In my code, when cursor is null i encounter the exception of CursorIndexOutOfBoundsException Index 0 requested, with a size of 0 in Android
How can I fix this problem??
public Cursor getCustAccount(long custRef){
openReadable();
Cursor cursor;
cursor = database.rawQuery(" SELECT CustAccountId AS _id,AccountNo as AccountNo,BankName as BankName,BranchName as BranchName FROM tblCustAccount WHERE CustRef =" + custRef , null);
if (cursor != null)
cursor.moveToFirst();
return cursor;
}
public ArrayList<String> getCustAccountString(long custRef) {
Cursor cursor = getCustAccount(custRef);
ArrayList<String> listAccount = new ArrayList<String>();
do {
listAccount.add(String.valueOf(cursor.getInt(1)));
} while(cursor.moveToNext());
return listAccount;
}
There's no data in the cursor. You should check that moveToFirst() succeeds before any of the get...() calls:
if (cursor.moveToFirst()) {
do {
listAccount.add(String.valueOf(cursor.getInt(1)));
} while(cursor.moveToNext());
}
use:-
if(cursor != null && cursor.moveToFirst()){
return cursor;
}
return null;
public abstract boolean moveToFirst ()
Move the cursor to the first row.
This method will return false if the cursor is empty.
Returns
whether the move succeeded.
try following code:
if (cursor.getCount() > 0) {
do {
listAccount.add(String.valueOf(cursor.getInt(1)));
} while(cursor.moveToNext());
}
Related
I've following table structure in my SQLite Database.
In my SqliteOpenHelper class, I wrote following method.
public Form getAllForms(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from "+FORM_TABLE, null);
int count = cursor.getCount();
String formID = cursor.getString(0);
Form form = new Form();
form.setId(formID);
cursor.close();
db.close();
return form;
}
I'm sure there's some data in it because I already watched count in debugging mode and I saw the quantity of row that actually existing in database. But CursorIndexOutOfBoundException shows up at cursor.getString(0). plus cursor.getInt(0) and cursor.getString(1) didn't work also. What's the problem might be?
You need to move the cursor to a valid row.
Valid rows are indexed from 0 to count-1. At first the cursor will point to row index -1 i.e. the one just before the first row.
The canonical way of looping through all rows is
if (cursor.moveToFirst()) {
do {
// now access cursor columns
} while (cursor.moveToNext());
}
Try this
try {
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
Form form = new Form();
form.setId(formID);
cursor.moveToNext();
}
} finally {
// database.close();
cursor.close();
dbHelper.close();
}
You need to call moveToFirst() to get to the first row before asking for values:
if ((cursor!= null) && (cursor.getCount() > 0)) {
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
}
So Simply use your code as
public Form getAllForms(){
Form form = new Form();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from "+FORM_TABLE, null);
if ((cursor != null) && (cursor.getCount() > 0)) {
cursor.moveToFirst();
while (cursor.isAfterLast() == false) {
String formID = cursor.getString(0);
form.setId(formID);
cursor.moveToNext();
}
cursor.close();
}
db.close();
return form;
}
I am trying to get all items from the table in sqlite and need to display it in List View.
Here is my code for getting Items
public List<MenuData> getMenuItem(){
SQLiteDatabase db;
Cursor cursor=null;
List<MenuData> menuList = new ArrayList<MenuData>();
db=getReadableDatabase();
String query ="SELECT * from "+TABLE_NAME_MENU;
try{
cursor = db.rawQuery (query, null );
}
catch (NullPointerException e){
Log.e("Error","Null Pointer Exception");
}
if ( cursor.moveToFirst()) {
do {
MenuData menuData= new MenuData();
menuData.setKEY_ITEM_NAME(cursor.getString(cursor.getColumnIndex(KEY_ITEM_NAME)));
menuData.setKEY_ITEM_CATEGORY(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CATEGORY)));
menuData.setKEY_ITEM_CONTENTS(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CONTENTS)));
menuData.setKEY_ITEM_TYPE(cursor.getString(cursor.getColumnIndex(KEY_ITEM_TYPE)));
menuData.setKEY_PRICE(cursor.getString(cursor.getColumnIndex(KEY_PRICE)));
menuList.add(menuData);
} while (cursor.moveToNext());
}
return menuList;
}
My problem is I got the result menuList of last row of the table and it has same number of rows in table. So the list view has all the same items.
Move the MenuData menuData= new MenuData() inside the do-while loop so you're creating new objects instead of updating the same object over and over again.
Also, change
if (cursor!=null) {
cursor.moveToFirst();
to
if (cursor.moveToFirst()) {
so your code doesn't crash in case there are no result rows. Checking for cursor != null is not really necessary.
plz correct your code with this structure
if(cursor.getCount() != 0 && cursor != null)
{
do
{
your values..
}while(cursor.moveToNext())
}
all data is store MenuData then Menudata values are attached to Listview..
Maybe you dont't close the cursor. my suggestion of code:
public List<MenuData> getMenuItem(){
List<MenuData> menuList = new ArrayList<MenuData>();
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery ("SELECT * from " + TABLE_NAME_MENU, null);
try {
if ( cursor.moveToFirst()) {
do {
MenuData menuData = new MenuData();
menuData.setKEY_ITEM_NAME(cursor.getString(cursor.getColumnIndex(KEY_ITEM_NAME)));
menuData.setKEY_ITEM_CATEGORY(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CATEGORY)));
menuData.setKEY_ITEM_CONTENTS(cursor.getString(cursor.getColumnIndex(KEY_ITEM_CONTENTS)));
menuData.setKEY_ITEM_TYPE(cursor.getString(cursor.getColumnIndex(KEY_ITEM_TYPE)));
menuData.setKEY_PRICE(cursor.getString(cursor.getColumnIndex(KEY_PRICE)));
menuList.add(menuData);
} while (cursor.moveToNext());
}
} finally {
// close the cursor
if(cursor != null) {
cursor.close();
}
} catch(Exception e) {
// handle exception
}
return menuList;
}
you have to change your last part of code to:
if(cursor != null && cursor.getCount() > 0){
while(cursor.moveToNext(){
// your code
}
}
... and are you sure that problem in this code?
Check your datalist. May be your problem in your adapter.
Hi i wants to count the total number of columns in android sqlite table, please guide that how to achieve? what i tried is below
public int numberOfColumns(String tableName) {
Cursor cursor = database.query(tableName, null, null, null, null, null, null);
if (cursor != null) {
if (cursor.getColumnCount() > 0) {
return cursor.getColumnCount();
} else {
return 0;
}
} else {
return 0;
}
}
this works fine, what i wants to know is about it is, this approach is fine or anything better i can do!!
i visited lot of stackoverflow links but still have confusion.
This works. There are some other methods such as PRAGMA table_info(tablename) but they aren't really that much better.
Checking for cursor != null is not necessary.
Also, it's a good idea to close your cursor before exiting the method.
You need to close your cursor after leaving the function, this change should work (not tested)
public int numberOfColumns(String tableName) {
int result = 0;
Cursor cursor = null;
try {
cursor = database.query(tableName, null, null, null, null, null,
null);
result = cursor.getColumnCount();
if (result < 0) {
result = 0;
}
} finally {
if (cursor != null)
cursor.close();
}
return result;
}
I have
public boolean isEmpty()
{
if (database == null) {
database = dbHelper.getReadableDatabase(); // or similar method that
}
Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM " + DatabaseHelper.TABLE_ENCOURAGEMENTS, null);
if (cursor != null) {
return false;
} else {
return true;
}
}
but the when I run it on an empty database, it crashes.
any suggestions?
the error is:
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View$1.onClick(View.java:2144)
Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0
Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0
I think you need to modify your condition to:
public boolean isEmpty() {
int count = -1;
if (cursor != null && cursor.moveToFirst()) {
count = cursor.getInt(0);
if (count > 0) {
return false;
}
else {
return true;
}
}
return true;
}
Explanation:
moveToFirst() is handy method that returns false if Cursor is empty. Checking whether Cursor is assigned to NULL isn't enough. You need to call it always you want to check status of your Cursor because also each Cursor is implicitly positioned before first row so you need to call it always.
Since you are selecting COUNT(*) so it always return at least one row with count value. You need to check this value whether is greather than zero or not. If yes, db is not empty.
Well, perhaps dbHelper is not returning a database. You should check again if the database is empty.
public boolean isEmpty()
{
if (database == null) {
database = dbHelper.getReadableDatabase(); // or similar method that
}
if (database != null) {
Cursor cursor = database.rawQuery("SELECT COUNT(*) FROM " + DatabaseHelper.TABLE_ENCOURAGEMENTS, null);
if (cursor != null) {
return false;
} else {
return true;
}
}
}
I frequently see code which involves iterating over the result of a database query, doing something with each row, and then moving on to the next row. Typical examples are as follows.
Cursor cursor = db.rawQuery(...);
cursor.moveToFirst();
while (cursor.isAfterLast() == false)
{
...
cursor.moveToNext();
}
Cursor cursor = db.rawQuery(...);
for (boolean hasItem = cursor.moveToFirst();
hasItem;
hasItem = cursor.moveToNext()) {
...
}
Cursor cursor = db.rawQuery(...);
if (cursor.moveToFirst()) {
do {
...
} while (cursor.moveToNext());
}
These all seem excessively long-winded to me, each with multiple calls to Cursor methods. Surely there must be a neater way?
The simplest way is this:
while (cursor.moveToNext()) {
...
}
The cursor starts before the first result row, so on the first iteration this moves to the first result if it exists. If the cursor is empty, or the last row has already been processed, then the loop exits neatly.
Of course, don't forget to close the cursor once you're done with it, preferably in a finally clause.
Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
...
}
} finally {
cursor.close();
}
If you target API 19+, you can use try-with-resources.
try (Cursor cursor = db.rawQuery(...)) {
while (cursor.moveToNext()) {
...
}
}
The best looking way I've found to go through a cursor is the following:
Cursor cursor;
... //fill the cursor here
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
// do what you need with the cursor here
}
Don't forget to close the cursor afterwards
EDIT: The given solution is great if you ever need to iterate a cursor that you are not responsible of. A good example would be, if you are taking a cursor as argument in a method, and you need to scan the cursor for a given value, without having to worry about the cursor's current position.
I'd just like to point out a third alternative which also works if the cursor is not at the start position:
if (cursor.moveToFirst()) {
do {
// do what you need with the cursor here
} while (cursor.moveToNext());
}
Below could be the better way:
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
//your code to implement
cursor.moveToNext();
}
}
cursor.close();
The above code would insure that it would go through entire iteration and won't escape first and last iteration.
How about using foreach loop:
Cursor cursor;
for (Cursor c : CursorUtils.iterate(cursor)) {
//c.doSth()
}
However my version of CursorUtils should be less ugly, but it automatically closes the cursor:
public class CursorUtils {
public static Iterable<Cursor> iterate(Cursor cursor) {
return new IterableWithObject<Cursor>(cursor) {
#Override
public Iterator<Cursor> iterator() {
return new IteratorWithObject<Cursor>(t) {
#Override
public boolean hasNext() {
t.moveToNext();
if (t.isAfterLast()) {
t.close();
return false;
}
return true;
}
#Override
public Cursor next() {
return t;
}
#Override
public void remove() {
throw new UnsupportedOperationException("CursorUtils : remove : ");
}
#Override
protected void onCreate() {
t.moveToPosition(-1);
}
};
}
};
}
private static abstract class IteratorWithObject<T> implements Iterator<T> {
protected T t;
public IteratorWithObject(T t) {
this.t = t;
this.onCreate();
}
protected abstract void onCreate();
}
private static abstract class IterableWithObject<T> implements Iterable<T> {
protected T t;
public IterableWithObject(T t) {
this.t = t;
}
}
}
import java.util.Iterator;
import android.database.Cursor;
public class IterableCursor implements Iterable<Cursor>, Iterator<Cursor> {
Cursor cursor;
int toVisit;
public IterableCursor(Cursor cursor) {
this.cursor = cursor;
toVisit = cursor.getCount();
}
public Iterator<Cursor> iterator() {
cursor.moveToPosition(-1);
return this;
}
public boolean hasNext() {
return toVisit>0;
}
public Cursor next() {
// if (!hasNext()) {
// throw new NoSuchElementException();
// }
cursor.moveToNext();
toVisit--;
return cursor;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Example code:
static void listAllPhones(Context context) {
Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
for (Cursor phone : new IterableCursor(phones)) {
String name = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.d("name=" + name + " phoneNumber=" + phoneNumber);
}
phones.close();
}
The Do/While solution is more elegant, but if you do use just the While solution posted above, without the moveToPosition(-1) you will miss the first element (at least on the Contact query).
I suggest:
if (cursor.getCount() > 0) {
cursor.moveToPosition(-1);
while (cursor.moveToNext()) {
<do stuff>
}
}
The cursor is the Interface that represents a 2-dimensional table of any database.
When you try to retrieve some data using SELECT statement, then the database will 1st create a CURSOR object and return its reference to you.
The pointer of this returned reference is pointing to the 0th location which is otherwise called as before the first location of the Cursor, so when you want to retrieve data from the cursor, you have to 1st move to the 1st record so we have to use moveToFirst
When you invoke moveToFirst() method on the Cursor, it takes the cursor pointer to the 1st location. Now you can access the data present in the 1st record
The best way to look :
Cursor cursor
for (cursor.moveToFirst();
!cursor.isAfterLast();
cursor.moveToNext()) {
.........
}
if (cursor.getCount() == 0)
return;
cursor.moveToFirst();
while (!cursor.isAfterLast())
{
// do something
cursor.moveToNext();
}
cursor.close();
Initially cursor is not on the first row show using moveToNext() you can iterate the cursor when record is not exist then it return false,unless it return true,
while (cursor.moveToNext()) {
...
}