Error with SQLite cursor - android

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.

Related

Android cursor.getColumnNames() doesn't contain the new added column

I use code below to test if a column exists:
public static boolean isColumnExists(String tableName, String columnName) {
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null);
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
return false;
}
The column hello2 doesn't exist in initial state, after adding column to database, the following test still tells that the column doesn't exist, and the second try will cause an error about duplicate column, which is not correct.
if (!isColumnExists("PositionCache", "hello2")) {
// First try will insert column to database
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
if (!isColumnExists("PositionCache", "hello2")) {
// Second try will give and error about duplicate column of hello2
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
I need to know the reason about such an abnormal phenomenon.
If I change SELECT * FROM to select * from in method isColumnExists then everything become normal.
I believe the reason is that SQLite (I strongly suspect the Cursor, so more correctly the Android SQLite aspect of the SDK) is cacheing data (perhaps because the underlying data is never retrieved from the Database as there is no need to get the data (as far as the Cursor is concerned)).
I've tried various checks including putting breakpoints in, checking the result of getColumnnames, and making the method non-static.
As soon as I add an alternative check using the PRAGMA table_info(*table_name*); then the column exists.
As such I'd suggest using the following :-
public static boolean isColumnExistsOld(String tableName, String columnName) {
Cursor csr = getDatabase().rawQuery("PRAGMA table_info(" + tableName + ")",null);
while(csr.moveToNext()) {
if (csr.getString(csr.getColumnIndex("name")).equalsIgnoreCase(columnName)) {
return true;
}
}
return false;
/*
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
cursor.moveToFirst();
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
boolean rv = colfound;
return false;
*/
}
Note your code has been left in but commented out.
I believe that evaluating forces the cache to be refreshed (i.e. I tried this an yep it does dynamically change to include the column).

return ArrayList<String> with specific record from SQLiteDataBase

I want to get values but the function always returns null. Even though I debug and there is value inside variable rv.
This is my method:
public ArrayList<String> getList(int id) {
try {
ArrayList<String> rv = new ArrayList<String>();
open();
Cursor c = db.rawQuery("select * from reviews where IDRE="+id, null);
if(c.moveToFirst() || c.getColumnCount()==1) {
rv.add(String.valueOf(c.getInt(c.getColumnIndex("IDRE"))));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("ID_FK"))));
rv.add(c.getString(c.getColumnIndex("DATE")));
rv.add(c.getString(c.getColumnIndex("TYPE")));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("COST"))));
rv.add(c.getString(c.getColumnIndex("SERVICE")));
rv.add(c.getString(c.getColumnIndex("ATMOSPHERE")));
rv.add(c.getString(c.getColumnIndex("OVERALL")));
rv.add(c.getString(c.getColumnIndex("COMMENT")));
}
c.close();
close();
return rv;
}catch(Exception e) {
return null;
}
}
Some logging would help determine if you're throwing an error and ending up in that catch block, as #Daniel Nugent is saying.
But I think the issue is with your if expression. c.moveToFirst is going to move your cursor to the first row of your data source, and then return true unless that data source is empty, so the only time that if block does not occur is when your data source is empty. The only way c.getColumnCount()==1 is having any effect on the evaluation of your expression is if you have a table with only one column and no rows. Let us know what you're trying to achieve with that, and add some logging, and we'll be better able to help you.
I have edited your code ...and given two example , you can refer any one...
public ArrayList<String> getList(int id) {
try {
ArrayList<String> rv = new ArrayList<String>();
open();
Cursor c = db.rawQuery("select * from reviews where IDRE="+id, null);
if(c==null)
return null;
c.moveToFirst();
rv.add(String.valueOf(c.getInt(c.getColumnIndex("IDRE"))));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("ID_FK"))));
rv.add(c.getString(c.getColumnIndex("DATE")));
rv.add(c.getString(c.getColumnIndex("TYPE")));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("COST"))));
rv.add(c.getString(c.getColumnIndex("SERVICE")));
rv.add(c.getString(c.getColumnIndex("ATMOSPHERE")));
rv.add(c.getString(c.getColumnIndex("OVERALL")));
rv.add(c.getString(c.getColumnIndex("COMMENT")));
c.close();
close();
return rv;
}catch(Exception e) {
return null;
}
}
Second way:
public ArrayList<String> getList(int id) {
try {
ArrayList<String> rv = new ArrayList<String>();
open();
String[] columns=new String[]{"IDRE","ID_FK","DATE","TYPE","COST","SERVICE","ATMOSPHERE","OVERALL","COMMENT"};
Cursor c=sql_db.query("reviews", columns, "IDRE"+"=?", new String[] {String.valueOf(id)}, null, null, null);
if(c==null)
return null;
c.moveToFirst();
rv.add(String.valueOf(c.getInt(c.getColumnIndex("IDRE"))));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("ID_FK"))));
rv.add(c.getString(c.getColumnIndex("DATE")));
rv.add(c.getString(c.getColumnIndex("TYPE")));
rv.add(String.valueOf(c.getInt(c.getColumnIndex("COST"))));
rv.add(c.getString(c.getColumnIndex("SERVICE")));
rv.add(c.getString(c.getColumnIndex("ATMOSPHERE")));
rv.add(c.getString(c.getColumnIndex("OVERALL")));
rv.add(c.getString(c.getColumnIndex("COMMENT")));
c.close();
close();
return rv;
}catch(Exception e) {
return null;
}
}

I can't get data from Cursor Object

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;
}

CursorIndexOutOfBoundsException android

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());
}

Getting exception while accessing sqlite database in android

I am trying to access sqlite database in my app and getting this exception:
12-27 11:32:12.760: E/Exception:(746): java.lang.IllegalStateException: attempt to acquire a reference on a close SQLiteClosable Exception occured in ContactListOfNumbersForWhichRuleIsAlreadySpecified() of DatabaseHandlerRule.java
I am using this code:
public ArrayList<String> ContactListOfNumbersForWhichRuleIsAlreadySpecified(DatabaseHandlerRule Activity)
{
ContactRule contact = null;
Cursor cursor = null;
SQLiteDatabase db = null;
ArrayList<String> contactList = null;
try
{
contactList = new ArrayList<String>();
// SQLiteActivity1.ReadingAllContactsRule(SplashActivity.s_dbRule);
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS + " WHERE "+KEY_NAME+" !='"
+"abcde#$%&*()##$%"+"'"+" AND "+KEY_PH_NO+"!='"+"abcde#$%&*()##$%"+"'"+" AND "+KEY_DATE+" ='"+"0"+"'";
db = this.getReadableDatabase();
if (!db.isOpen()) {
db = SQLiteDatabase.openDatabase(
"/data/data/com.velosys.smsManager/databases/rulesManager",
null, SQLiteDatabase.OPEN_READWRITE);
}
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
contact = new ContactRule();
contact.setID(Integer.parseInt(cursor.getString(0)));
contact.setName(cursor.getString(1));
contact.setPhoneNumber(cursor.getString(2));
contact.setFolderName(cursor.getString(3));
contact.setParentFolderAddress(cursor.getString(4));
contact.setTime(cursor.getLong(5));
contact.setDate(cursor.getLong(6));
// Adding contact to list
contactList.add(contact.getName());
} while (cursor.moveToNext());
}
else if(!cursor.moveToFirst())
{
Log.e("Message: ","Rule is not specified for even a single number in database");
return contactList;
}
}
catch(Exception e)
{
Log.e("Exception: ",e+" Exception occured in ContactListOfNumbersForWhichRuleIsAlreadySpecified() of DatabaseHandlerRule.java");
}
finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}
return contactList;
}
I have searched for the reasons behind this exception but nothing implies to my case:
I am not trying to write but read the database.Hence no question arises here about concurrency.
I am using instance of Database helper class in db = this.getReadableDatabase();
I am closing database properly each and everytime i open it.
Please help me.Thanks in advance.
Edit:
Its strange.After removing finally and putting the code without finallly block,everything is working fine.Can anyone please tell me the reason behind this?
//finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}
Please remove finally block. in that you have close db and cursor so it this error comes.
In the statement db = this.getReadableDatabase();, I'm not sure of what context you are using. So declare a global context like Context context = this; then call that statement as db = context.getReadableDatabase();
Its strange.After removing finally and putting the code without finallly block,everything is working fine.Can anyone please tell me the reason behind this?
//finally
{
if(cursor != null && !cursor.isClosed())
cursor.close();
if(db != null && db.isOpen())
db.close();
}

Categories

Resources