I'm trying to insert values from a cursor to my database, but I get an error.
Here's what I do -
Cursor getUserDrinks = myDbHelper.getUserDrinks();
if(getUserDrinks != null)
{
if (getUserDrinks.moveToFirst()){
do{
ContentValues initialValues = new ContentValues();
initialValues.put("code", getUserDrinks.getInt(getUserDrinks.getColumnIndex("code")));
initialValues.put("imgstr", getUserDrinks.getString(getUserDrinks.getColumnIndex("imgstr")));
initialValues.put("name", getUserDrinks.getString(getUserDrinks.getColumnIndex("name")));
initialValues.put("alc", getUserDrinks.getDouble(getUserDrinks.getColumnIndex("alc")));
initialValues.put("user", 1);
try {
myDataBase.beginTransaction();
myDataBase.insert("drinks", null, initialValues);
myDataBase.setTransactionSuccessful();
}
finally {
myDataBase.endTransaction();
}
}while(getUserDrinks.moveToNext());
}
}
But it gives me a CursorIndexOutOfBoundsException. Here's the Log -
04-30 13:22:35.363: ERROR/AndroidRuntime(19161): java.lang.RuntimeException: Unable to start activity ComponentInfo{android.alco/android.alco.main}: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
I know that the Cursor is not empty.
What am I doing wrong?
The problem is that moveToNext() returns false when you are already positioned after the last element and want go further. Range of valid positions is from -1 to elementCount inclusive, so the last position is legitimate, but there's no element. This is what really happens in your code if the cursor has two positions:
You call moveToFirst(), cursor is positioned at the first element with index 0.
You read the values and call moveToNext(). Movement succeeds, you are positioned at index 1.
You read the values and call moveToNext(). Movement succeeds, you are positioned at index 2, which is beyond the last element.
You try to read the values and fail because there is no element with index 2.
What you need to do is the following:
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
//Read the contents
cursor.moveToNext(); //Advance to the next element
}
Related
I want to get data from an SQLite table and I know that table will always have only one record. I'm trying to do that get using:
public User_Token getUser_TokenDB() {
String sql = "SELECT * FROM " + TABLE_NAME_USER_TOKEN +" WHERE ID = " + 1;
Cursor cursor = this.database.rawQuery(sql, null);
User_Token auxUserToken = new User_Token(
cursor.getLong(0),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3));
return auxUserToken;
}
But I always get:
'java.lang.RuntimeException: Unable to start activity ComponentInfo{com.support.android.iplfit/com.support.android.iplfit.Activities.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0'.
The only way I can access this information is by returning an array of Tokens and do .get(0) but I feel like it is not the right way, since it has no sense to return an array of only one object.
The cursor index starts out of bounds. You need to use Cursor#moveToFirst() which moves the cursor to the 0 index and returns true if there are items in the cursor.
So something like this:
if (cursor.moveToFirst()) {
// Cursor has items and is ready for extraction
} else {
// Cursor has no items.
}
You need to move cursor at first row before you can get data from it. Call moveToNext method before accessing data from cursor
while(cursor.MoveToNext()) {
User_Token auxUserToken = new User_Token(
cursor.getLong(0),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3));
}
You aren't moving to a position within the cursor, thus the location is before any rows i.e. -1.
You need to move to a row and in your case you want the first row (not that there are any (i.e. the message says size of 0)) and only if the move can be made do you want to extract data. Otherwise you would handle no data available.
The Cursor move???? methods (moveToFirst, moveToLast, moveToNext, moveToPrevious, moveToPosition) all return true if the move can be made, otherwise false.
So your code code be :-
Cursor cursor = this.database.rawQuery(sql, null);
if (cursor.moveToFirst) {
User_Token auxUserToken = new User_Token(
cursor.getLong(0),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3));
} else {
return null; //???? handle no data how you want perhaps null.
}
return auxUserToken;
As a note it's inadvisable to generally use column offsets, rather the more common way is to get the offset according to the column name using getColumnIndex(column_name). So (assuming the column name is id) would be to replace cursor.getLong(0) with cursor.getLong(cursor.getColumnIndex("id")
I have an SQLite db. This is the table below. It's getting added.
public boolean addAllCampaign(Allcampaigndata allcampaigndata) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(ALLCAMP_ID, allcampaigndata.getAllCampid());
contentValues.put(ALLCAMP_NAME, allcampaigndata.getAllCampName());
contentValues.put(ALLVIEWS, allcampaigndata.getAllViews());
contentValues.put(ALLDESTROY, allcampaigndata.getAllDestroy());
contentValues.put(ALLENDOFCAMP,allcampaigndata.getAllEndofcamp());
db.insert(TABLE_NAME_EIGHT, null, contentValues);
db.close();
return true;
}
Now I have a method which has a query:
public Cursor getoneCampaign(int allcampaignid) {
SQLiteDatabase db = this.getReadableDatabase();
String sqleight = "SELECT * FROM Allcampaigndata WHERE allcampaid =?";
Cursor d= db.rawQuery(sqleight, null);
return d;
}
I am calling this method from here:
private void shownextcamp(int allcampaignid){
Cursor d =db.getoneCampaign(allcampaignid);
newcamid=d.getString(0);
Toast.makeText(getApplicationContext(),"Newcampid :"+newcamid,LENGTH_LONG).show();
d.moveToFirst();
}
I am getting the below error. Just cannot figure out why:
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1
requested, with a size of 0
I use this method:
private void shownextcamp(int allcampaignid){
Cursor d =db.getoneCampaign(allcampaignid);
if (null == d) {
return;//return 0;
}
while (d.moveToNext()){
for (int i = 0;i < d.getColumnCount();i++){
String columnName = d.getColumnName(i);
Toast.makeText(mContext.getApplicationContext()
,columnName+"(Newcampid) :"+d.getString(d.getColumnIndex(columnName))
,Toast.LENGTH_SHORT).show();
}
}
d.close();
}
Android.database.cursorindexoutofboundsexception exception occurs in d.getString(0);
This line of code, need to add if (d.moveToFirst ()) {} This judgment
The "SELECT * FROM Allcampaigndata WHERE allcampaid =?" parameter in db.rawQuery(sqleight, null) specifies that column information is to be returned, or null if all columns are returned, but this is less efficient
There are two potential issues with your code.
One is that a newly created cursor is positioned BEFORE any rows (position -1). So without moving the cursor to a row you are trying to access a non-existent row. The second is that if there are no rows returned from the query then again there would be no rows. The first of these was the cause of the error (index -1 with a size of 0).
You could code :-
private void shownextcamp(int allcampaignid){
Cursor d =db.getoneCampaign(allcampaignid);
if (d.getCount > 0) {
d.moveToFirst();
newcamid=d.getString(0);
Toast.makeText(getApplicationContext(),"Newcampid :"+newcamid,LENGTH_LONG).show();
} else {
//handle no row
}
}
This a) checks if there are any rows and if so b) moves to the first row (overcoming both issues).
or if you expect one or multiple rows then use to replace the if construct above (note no handling of 0 rows in this, but checking count via d.getCount() could be added) :-
while (d.moveToNext()) {
newcamid=d.getString(0);
Toast.makeText(getApplicationContext(),"Newcampid :"+newcamid,LENGTH_LONG).show();
}
moveToNext will effectively return false if there are no rows and if at the BEFORE position will move to the first row any subsequent iterations will move to the next record, finishing the while loop when there are no more rows due to the effective false raised.
in my android application i used the following function to retrieve the column from the table..the table contains value but it has an exception.
public String[] getactivelist(){
Log.v("ppp","getactivelist");
String[] actname=new String[50];
SQLiteDatabase db = this.getWritableDatabase();
Log.v("ppp","dbcrtd");
Cursor cursor = db.rawQuery("SELECT name FROM activelist ORDER BY time ASC", null);
Log.v("ppp","aftrcurser");
int i=0;
Log.v("ppp crsr",cursor.getString(0));
if (cursor.moveToFirst()) {
do {
actname[i]=cursor.getString(0);
Log.v("ppp crsr",cursor.getString(0));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return actname;
}
the log cat shows the following error
04-04 01:19:41.170 2581-2601/com.example.pranavtv.loudspeaker V/pppīš tryandroid.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2
In your line
Log.v("ppp crsr", cursor.getString(0));
You try to get a string from the cursor. If there aren't any lines, it should throw the error observed.
You are calling the following line...
Log.v("ppp crsr",cursor.getString(0));
...before you have moved the position of your Cursor using...
if (cursor.moveToFirst()) {
By default, the position of a Cursor is initially set to be -1 which is before the first valid position as the first position which contains data is position 0.
Simply remove that line (the one before the if(...)) and you should be good to go.
On another note, in your do...while loop you are using...
actname[i]=cursor.getString(0);
...but you never increment i. Consequentially you will only ever modify actname[0] regardless of how many results are returned to the Cursor.
in my activity ineed to check whether the table exist or not for that im using
Cursor cursor = marksdb.rawQuery("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='"+classt+"'", null);
im getting 1 if table exist 0 otherwise
for that i need check value in cursor for that im using
if(cursor.getCount()==1){
// get values from cursor here
callclasstb();
}
else{
tv.setVisibility(View.VISIBLE);
subjectet.setEnabled(false);
markset.setEnabled(false);
markssp.setEnabled(false);
}
but in all cases im getting value 1 because getcout() returns a value 1 r 0 and
callclasstb();
is not executing what condition i need to write in if{....} to make it execute
cursor.getCount() in your case will always return 1 (the number of "rows" in your resultset). you need to figure out what was returned via the cursor.
Cursor cursor = marksdb.rawQuery(...);
cursor.moveToFirst(); // first "row"
int nTableExists = cursor.getInt(0);
cursor.close();
if (nTableExists) { // != 0
...do something...
}
I always use the code below to get all the informations
But I have question that c.movetoNext lead to skip the first row of result set
Please tell me what really happens behind the surface so that I can fully understand it
SQLiteDatabase db;
Cursor c = db.query("pic", null, null, null, null,null, null);
c.moveToFirst();
while(c.movetoNext)
{
//do something
//example: String a=c.getString(0);
}
You're calling moveToFirst(), which positions the cursor on the first row, then your while loop calls moveToNext() before entering the loop, which results in the first row being skipped.
You can solve it with either a do...while loop, or a for loop such as
for( c.moveToFirst(); !c.isAfterLast(); c.moveToNext() ) {
// Stuff
}
A late answer, but hopefully useful to others finding this page. I've been using an: "if () do { } while();" loop. The "moveToFirst()" function returns false if no rows were returned in the cursor. The "moveToNext()" function returns false when past end of cursor:
Cursor c = db.query(......);
if (c.moveToFirst()) do {
data = c.getString(0) // eg. get value from first column in cursor
// do something more
} while (c.moveToNext());
c.close();
(which is similar to TactMayers' answer).
According to the Cursor documentation, "query... Returns: A Cursor object, which is positioned before the first entry". It further seems that queries get executed only when methods are called on the cursor. Hope that helps.
c.moveToFirst();
This line move the cursor to the first row.
while(c.movetoNext)
After running this line of code, the cursor will move to next row (row 2 for the first run of the while loop.) So by the time the code enter the loop, the cursor is pointing to row 2 already and can never access the first row.
Try replacing the while loop like this
do {
// do something
} while(c.movetoNext())
Actually, you do not have to call c.moveToFirst(); at all