android cursor.moveToNext()? - android

I am trying to query all the columns in a table into one long text view and/or string. I know this might not be the right way to do things but I have to do this. Correct me if I am wrong, I was under the impression that move next would get the next column in the row:
Cursor c = db.get();
if(c.moveToFirst){
do{
string = c.getString(0);
}while(c.moveToNext);
}
I thought that this would get the first column and display all of its contents instead I get the first column and first row. What am I doing wrong? Is there a better or real way to get this information without using a ListView?

The simple use is:
Cursor cursor = db.query(...);
while (cursor.moveToNext()) {
...
}
moveToFirst is used when you need to start iterating from start after you have already reached some position.
Avoid using cursor.getCount() except if it is required.
And never use a loop over getCount().
getCount is expensive - it iterates over many records to count them. It doesn't return a stored variable. There may be some caching on a second call, but the first call doesn't know the answer until it is counted.
If your query matches 1000 rows, the cursor actually has only the first row. Each moveToNext searches and finds the next match. getCount must find all 1000. Why iterate over all if you only need 10? Why iterate twice?
Also, if your query doesn't use an index, getCount may be even slower - getCount may go over 10000 records even though the query matches only 100. Why loop 20000 instead of 10000?

For clarity a complete example would be as follows which I trust is of interest. As code comments indicated we essentially iterate over database rows and then columns to form a table of data as per database.
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null,
null);
//if the cursor isnt null we will essentially iterate over rows and then columns
//to form a table of data as per database.
if (cursor != null) {
//more to the first row
cursor.moveToFirst();
//iterate over rows
for (int i = 0; i < cursor.getCount(); i++) {
//iterate over the columns
for(int j = 0; j < cursor.getColumnNames().length; j++){
//append the column value to the string builder and delimit by a pipe symbol
stringBuilder.append(cursor.getString(j) + "|");
}
//add a new line carriage return
stringBuilder.append("\n");
//move to the next row
cursor.moveToNext();
}
//close the cursor
cursor.close();
}

I am coding my loops over the cusror like this:
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
cursor.getString(cursor.getColumnIndex("column_name"));
cursor.moveToNext();
}
That always works. This will retrieve the values of column "column_name" of all rows.
Your mistake is that you loop over the rows and not the columns.
To loop over the columns:
cursor.moveToFirst();
for(int i = 0; i < cursor.getColumnNames().length; i++){
cursor.getString(i);
}
That will loop over the columns of the first row and retrieve each columns value.

moveToNext move the cursor to the next row. and c.getString(0) will always give you the first column if there is one. I think you should do something similar to this inside your loop
int index = c.getColumnIndex("Column_Name");
string = c.getString(index);

cursor.moveToFirst() moves the cursor to the first row. If you know that you have 6 columns, and you want one string containing all the columns, try the following.
c.moveToFirst();
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i < 6; i++){
stringBuilder.append(c.getString(i));
}
// to return the string, you would do stringBuilder.toString();

Related

Couldn't read row and column from CursorWindow

I'm trying to fill in a two-dimensional array, with data from my DB SQLite. But the following happens:
It's my first time with SQLite, by the way, and I was trying to find out if there was something like a "Result Set" or a "Data Table" ... and I found the so-called "Cursor". Ok, I started using it ... inserting a single row in each table (all normal) but now when I insert another row in my subject table, the application crashes when I try to navigate in the cursor.
E/CursorWindow: Failed to read row 6, column 6 from a CursorWindow which has 12 rows, 6 columns.
My table is only made up of 6 columns, and as for the data, the same application shows me that it has 2 rows, but for some reason it only reads the data from the first row and the other rows not.
public String[][] getMaterias(){
String[][] materias = new String[rows][6];
Cursor cursor = admin.selectLog(DBScheme.Tabla_Materias);
cursor.moveToFirst();
try {
for(int f = 0; f < rows; f++){
for(int c = 0; c < 6; c++){
materias[f][c] = cursor.getString(cursor.getPosition());
cursor.moveToNext();
}
}
}catch (IllegalStateException ex){
ex.printStackTrace();
}
return materias;
}
I doubt very much that I have to do something like change the version of the database, since I have not touched the schema of the DB, only the only thing I have done was add another row of data. How I can solve this guys?
E/CursorWindow: Failed to read row 6, column 6 from a CursorWindow
which has 12 rows, 6 columns.
The above message is quite explantory, but you need to think in terms of offsets. That is you have a Cursor with 12 rows and 6 columns (from a CursorWindow which has 12 rows, 6 columns).
That means that you can use offsets 0 to 5 for the columns and that there is no column 6 (offset).
Using position as the column index, as per materias[f][c] = cursor.getString(cursor.getPosition()); will always result in such an error if the number of rows in the cursor exceeds the number of columns in the table.
You may wish to consider the following as not only a fix for the issue but also as perhaps a more adaptable solution (i.e there is no reliance on fixed/hard coded numbers as the number of rows and the number of columns is determined according to the Cursor)
public String[][] getMaterias(){
Cursor cursor = admin.selectLog(DBScheme.Tabla_Materias);
String[][] materias = new String[cursor.getCount()][cursor.getColumnCount()];
while(cursor.moveToNext())
for(int c = 0; c < cursor.getColumnCount(); c++){
materias[cursor.getPosition()][c] = cursor.getString(c);
}
}
return materias;
}
Perhaps even consider making it even more generic by passing a cursor (any cursor) as per :-
public String[][] getMaterias(Cursor cursor){
String[][] materias = new String[cursor.getCount()][cursor.getColumnCount()];
while(cursor.moveToNext())
for(int c = 0; c < cursor.getColumnCount(); c++){
materias[cursor.getPosition()][c] = cursor.getString(c);
}
}
return materias;
}
I feel very embarrassed to ask something really stupid ... the solution was in my eyes all this time:
I just had to change cursor.getPosition() with the c variable:
for(int f = 0; f < rows; f++){
for(int c = 0; c < 6; c++){
materias[f][c] = cursor.getString(c);
cursor.moveToNext();
}
}
I´m really sooorry....

Android database update records

In a table of my database, I have 7 records.
Now I want to update the records through a WHERE clause.
First, count the records, according to a clause
int pos = 0;
String SQL = "SELECT COUNT(posizione) FROM operatori WHERE posizione>0;";
final Cursor cur = db2.rawQuery(SQL, null);
while (cur.moveToNext()) {
pos = cur.getInt(0);
}
cur.close();
//then, with a for loop, update all the records based on a WHERE clause
for (int i = 1; i <= pos; i++) {
ContentValues cv1 = new ContentValues();
cv1.put(OperatoriTable.POSIZIONE, i);
db2.update(OperatoriTable.TABLE_NAME, cv1, OperatoriTable.POSIZIONE + ">0", null);
}
db2.close();
but, for example, if posequals 5, should enter the numbers 1,2,3,4,5. Instead, it is always inserted 1. Where am I wrong?
Your update statement probably updates multiple rows at once.
Each time you call db2.update in the for loop, it probably overwrites all rows where posizione>0 with the value currently in cv1.

sqlite cursorindexoutofbound exception

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.

Retrieve the contents of first three rows of a android database using a cursor

Currently in my code i'm using a cursor to retrieve the entire database
My code is
public Cursor getAll() {
return (getReadableDatabase().rawQuery(
"SELECT _id, note, amt, dueDate FROM New", null));
}
The function of retrieving the contents is to populate the same in a listview.
Now I want to retrieve the contents of the first three rows of the same database using cursor to display in another listview.
Need Help, Thanks in Advance.
The correct way to do it is to limit the result number to three:
"SELECT _id, note, amt, dueDate FROM New ORDER BY _id LIMIT 3"
Then you just iterate over the cursor (as usual)
Since you've already obtained a Cursor, in order to get the first three rows of the result, you do this:
Cursor cursor = getAll();
cursor.moveToFirst();
int count = 0;
while(!cursor.isAfterLast() && count < 3)
{
// Grab your data here using cursor.getLong(0), cursor.getString(1) etc.
// and store it an array.
count++;
cursor.moveToNext();
}
cursor.close();
You may want to limit the query results to at most three by adding a LIMIT 0,3 statement to your SQL. Having obtained an array of at most three elements containing your records, you can then proceed to place them in the other ListView you are referring to. You do this by adding them to this ListView's source array. Then call the ListView adapter's notifyDataSetChanged method to have it update itself.
So you can do this in two ways:
Create a separate select:
SELECT * FROM Table_Name LIMIT 3;
Select three rows from cursor:
int n = 0;
cursor.moveToFirst();
while (!cur.isAfterLast() && n < 3) {
// Use the data
n++;
cur.moveToNext();
}
cur.close();

Error when accessing cursor elements

I'm trying to get all the IDs in the table by cursor. The table has 4 rows, and when I try to access the cursor by any index aside from 0 , the App crashes.
Guys, the problem still exists and even c.getInt(0) doesn't work...I really dont know where my mistake is???
the logcat also suggests that the error might be comes from
Toast.makeText(getApplicationContext(), "id="+dbd.getIDs()[0], Toast.LENGTH_SHORT).show();
I mean c.getint(0) returns the id, c.getint(2) returns error. Here is the code:
public int []getIDs() {
SQLiteDatabase db = this.getReadableDatabase();
SQLiteCursor c = (SQLiteCursor) db.rawQuery("SELECT " + BaseColumns._ID + " FROM Demo ", null);
int []r = new int[c.getCount()];
c.moveToFirst();
do{
r[c.getPosition()] = c.getInt(0);
}while(c.moveToNext());
c.close();
db.close();
return r;
}
Your select is a projection onto the ID column (select columns from ..., columns are the column ids you are interested in, and you specified just one). Thus the answer just has one column, namely the ID. Any access to columns with index > 0 will not work.
To access the other columns name them in the projection in your query.
c.getInt(0) return only value of first colunn from current row.
try this code:
do{
int r = c.getInt(0);
Log.d("Your class name","id value = "+r);
}while(c.moveToNext());
You can imagine Cursor as a table. There are rows and columns. And a cursor is pointing on a particular row in this table. Thus, to get all id's you should move across all rows.
c.getInt(ind) In this statement index is pointing on the column with index ind. Thus, in your code you try to get the second and third column and according to your code there is no these column.
To get a proper code you should create a loop and traverse all rows of your cursor. Also you should use c.getInt(0) to get the columns values.
Assuming you are selecting the appropriate Data, your problem is that you're not preparing the Cursor to be iterated.
Before iterating, call:
c.moveToFirst();
Like this:
int []r = new int [c.getCount()];
c.moveToFirst();
do{
r[c.getPosition()] = c.getInt(0);
}while(c.moveToNext());
c.close();
db.close();
return r;
This is well indicated in LogCat. I can't remember how it's put, but the message is very suggestive. Please post as much of the Log as possible, especially the good bits.
Also, I modified 'r' to be an array. As it was you were only returning the value of the last row.

Categories

Resources