I am a programming newbie
and I found this piece of code in the internet and it works fine
Cursor c=db.query(DataBase.TB_NAME, new String[] {DataBase.KEY_ROWID,DataBase.KEY_RATE}, DataBase.KEY_ROWID+"= 1", null, null, null, null);
if(c!=null)
{
c.moveToFirst();
}
but I am not able to understand the use of the
if(c!=null)
{
c.moveToFirst();
}
part. What does it do exactly , and if I remove the
if(c!=null) { c.moveToFirst(); }
part, the code doesn't work.
The docs for SQLiteDatabase.query() say that the query methods return:
"A Cursor object, which is positioned before the first entry."
Calling moveToFirst() does two things: it allows you to test whether the query returned an empty set (by testing the return value) and it moves the cursor to the first result (when the set is not empty). Note that to guard against an empty return set, the code you posted should be testing the return value (which it is not doing).
Unlike the call to moveToFirst(), the test for if(c!=null) is useless; query() will either return a Cursor object or it will throw an exception. It will never return null.
if (c.moveToFirst()) {
while(!c.isAfterLast()) { // If you use c.moveToNext() here, you will bypass the first row, which is WRONG
...
c.moveToNext();
}
}
Cursor is not a Row of the result of query. Cursor is an object that can iterate on the result rows of your query. Cursor can moves to each row. .moveToFirst() method move it to the first row of result table.
moveToFirst() method moves the cursor to the first row. It allows to perform a test whether the query returned an empty set or not. Here is a sample of its implementation,
if (cursor.getCount() == 0 || !cursor.moveToFirst()) {
return cursor.getLong(cursor.getColumnIndexOrThrow(ID_COLUMN));
cursor.close();
what macio.Jun says is right!
we have code like below:
String sql = "select id,title,url,singer,view,info from cache where id=" + id;
SQLiteDatabase db = getMaintainer().getReadableDatabase();
Cursor query = db.rawQuery(sql, null);
query.moveToFirst();
while(query.moveToNext()){
DBMusicData entity = new DBMusicData();
entity.setId(query.getString(query.getColumnIndex(FIELD_ID)));
entity.setTitle(query.getString(query.getColumnIndex(FIELD_TITLE)));
entity.setSinger(query.getString(query.getColumnIndex(FIELD_SINGER)));
entity.setTitlepic(query.getString(query.getColumnIndex(FIELD_PICURL)));
entity.setInfoUrl(query.getString(query.getColumnIndex(FIELD_INFO)));
entity.setViews(query.getString(query.getColumnIndex(FIELD_VIEW)));
Log.w(tag, "cache:"+ entity.toString());
}
query.close();
query=null;
db.close();
db=null;
If we have only one record in the cache table, query.moveToFirst(); will cause that no record returns.
Related
I am using custom adapter extending cursor adapter for displaying data in listview, to display particular phone number i have passed the id to a method in database class but it is showing
errorandroid.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
while placing debugger in the the method it is not going after the line
num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
Can any one help me to solve it.
This is the code:
public String getNumberFromId(int id)
{
String num;
db= this.getReadableDatabase();
Cursor cursor = db.query(scheduletable, new String[] { "ContactNumber" },"_id="+id, null, null, null, null);
cursor.moveToFirst();
num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
cursor.close();
db.close();
return num;
}
Whenever you are dealing with Cursors, ALWAYS check for null and check for moveToFirst() without fail.
if( cursor != null && cursor.moveToFirst() ){
num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
cursor.close();
}
Place logs appropriately to see whether it is returning null or an empty cursor. According to that check your query.
Update Put both the checks in a single statement as mentioned by Jon in the comment below.
Update 2 Put the close() call within the valid cursor scope.
try this.. this will avoid an Exception being thrown when the cursor is empty..
if(cursor != null && cursor.moveToFirst()){
num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
cursor.close();
}
First check this Condition before fetching data
if(cursor!=null && cursor.getCount()>0){
cursor.moveToFirst();
num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
}
Check the return value from moveToFirst(), before you try to read anything from the cursor. It looks as if no results are being returned.
a save schema to query Cursors is
// just one
Cursor cursor = db.query(...);
if (cursor != null) {
if (cursor.moveToFirst()) {
value = cursor.getSomething();
}
cursor.close();
}
// multiple columns
Cursor cursor = db.query(...);
if (cursor != null) {
while (cursor.moveToNext()) {
values.add(cursor.getSomething());
}
cursor.close();
}
In case people are still looking:
Instead of searching for "ContactNumber" try searching for Phone.NUMBER. The tutorial has the code with more details: http://developer.android.com/training/basics/intents/result.html
try to uninstall the app and then again test it... actually the sqlite db is created only once when the app is first install... so if you think your logic is current then reinstalling the app will do the trick for you. !!!!
My query return 198 registers but cursor only read one register.
Why?
The mCount property of Cursor show 198.
This code:
public ArrayList<EnderecoOficina> retornarListaEnderecoOficina(String sCampo,
String sWhere) {
ArrayList<EnderecoOficina> lista = new ArrayList<EnderecoOficina>();
String query = String.format("SELECT %s FROM %s WHERE %s",
sCampo,
MyDBConstants.TABLE_OFICINAS,
sWhere);
SQLiteDatabase db = dbHandler.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
int i = 0;
if (cursor != null && cursor.moveToFirst()){
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
} while (cursor.moveToNext());
cursor.close();
db.close();
return lista;
}
image link (my points not allow attach image here).
I think you're confusing while syntax.
while (cursor.moveToNext());
Will loop without doing anything until the Cursor is empty. I think you wanted a do/while as explained by CommonsWare answer.
In my opinion, this is an unnecessary complicated way to do it. A lot of people don't know how to use Android Cursor. I've seen all kinds of complicated ways to do it (checking for null, moving to first, moving to index...), but this is the simplest way:
try {
// Loop while there are records on the Cursor
while (cursor.moveToNext()) {
EnderecoOficina item = new EnderecoOficina(i++,
cursor.getString(0),
cursor.getString(1),
cursor.getString(2));
lista.add(item);
}
} finally {
// Make sure the cursor is closed no matter what
cursor.close();
}
There's no need to check for null, Android Cursor API never returns a null cursor. You also need to close the Cursor once you've finished with it.
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
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;
}
I query the table by using this function below
public Cursor getTableInfo() throws SQLException
{
return db.query(TableName, null,
null,
null,
null,
null,
null);
}
I got the error "View Root.handleMessage(Message)line:1704". I could insert the data but can't query the data. I called this function below
Cursor c = db.getTableInfo();
int cRow = c.getCount();
if (cRow == 0)
{
Toast.makeText(NewContact.this,
"No Record",
Toast.LENGTH_LONG).show();
}
In SQLite, is there any case-sensitive in the name of database, table, column?
Please help me.
Your db request looks ok and it should return all records from your table.
So maybe there are just no records in the table?
Also it's unclear whether you have problem with db related stuff or with smth else, because the code provided looks ok.
I would rather evaluate the outcome of c.moveToFirst() instead of c.getCount(). The latter means the cursor iterates over the whole dataset which is a more costly operation.