This question already has answers here:
Iterate through rows from Sqlite-query
(7 answers)
Closed 6 years ago.
I used a While Loop to add the values of an SQL table into an ArrayList using the Cursor class, but at the moment of adding all the values, the While Loop stop giving values but, at the same time, it doesn't continue with the next statements. I used the condition that: if inside the While Loop the Cursor has null value, it needs to stop (c != null), it stops but doesn't continue. I used Log.i to see if I receive values after the While Loop, but I don't get any value. Here is the code I am using:
static ArrayList<String> notes = new ArrayList<>();
static ArrayAdapter arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
try{
SQLiteDatabase sqLiteDatabase = this.openOrCreateDatabase("Notes",MODE_PRIVATE, null);
sqLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS notes (name VARCHAR)");
sqLiteDatabase.execSQL("INSERT INTO notes (name) VALUES ('LUIS GA')");
sqLiteDatabase.execSQL("INSERT INTO notes (name) VALUES ('LUIS')");
sqLiteDatabase.execSQL("INSERT INTO notes (name) VALUES ('GA')");
Cursor c = sqLiteDatabase.rawQuery("SELECT * FROM notes", null);
int nameIndex = c.getColumnIndex("name");
notes.add("example note");
c.moveToFirst();
arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, notes);
listView.setAdapter(arrayAdapter);
int i = 0;
Log.i("Bucefalo", Integer.toString(i));
while(c != null){
Log.i("Dato",c.getString(nameIndex));
notes.add(c.getString(nameIndex));
c.moveToNext();
i++;
Log.i("Luis", Integer.toString(i));
};
i = 2;
Log.i("Napoleon", Integer.toString(i));
String Hercules = "Hercules";
Log.i("Hercules",Hercules);
}
catch (Exception e){
e.printStackTrace();
}
The values that I receive in the Logcat using Log.i, are "Bucefalo" and "Luis" (the one inside the While Loop), but I don't receive the value "Napoleon" and "Hercules", Why? How I can fix this? Thank you
This is the best way to iterate through the cursor
Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
...
}
} finally {
cursor.close();
}
Aside the wrong usage of the cursor, this code
while(c != null){
...
c.moveToNext();
}
should actually never stop looping.
You see: you have a local reference c there. It is not null. Calling a method on a reference absolutely can not turn the reference itself to be null. Only an assignment like c = null would you get there.
In other words: your claims about observed behavior are not supported by the code you are posting.
moveToNext returns a boolean value, but at the same time it goes ahead and moves the cursor.
Use like this,
Cursor c = sqLiteDatabase.rawQuery(....);
while (c.moveToNext()) {
}
or
do {
} while (c.moveToNext());
There is a syntax error in your while Loop.it should be below
while (expression)
{
statemets(s)
}
and moreover you are using cursor badly.
you can use
cur.moveToFirst();
while (cur.isAfterLast() == false) {
.............
............
cur.moveToNext();
}
cur.close();
or
Cursor cursor = db.rawQuery(...);
if (cursor.moveToFirst()) {
do {
...
} while (cursor.moveToNext());
}
or
Cursor cursor = db.rawQuery(...);
try {
while (cursor.moveToNext()) {
...
}
} finally {
cursor.close();
}
Related
I am new to programming for Android devices. I have two activities, in the first activity I send an integer value from the first activity to the second activity.
How can I add this variable in sqlite query which I receive from my first activity?
I want to add booknumber where in query written b=1 I want replace 1 with booknumber
private void setData() {
Intent mIntent = getIntent();
int booknumber= mIntent.getIntExtra("booknumber", 0);
stringArrayList = new ArrayList<>();
mDBHelper = new DatabaseHelper(this);
mDb = mDBHelper.getReadableDatabase();
Cursor cursor = mDb.rawQuery("select DISTINCT c from t_asv where b=1", new String[]{});
if(cursor!=null && cursor.getCount() > 0)
{
if (cursor.moveToFirst())
{
do {
stringArrayList.add(cursor.getString(0));
} while (cursor.moveToNext());
}
}
Just Concatenate the int booknumber to your query like below:
int booknumber= mIntent.getIntExtra("booknumber", 0);
...
Cursor cursor = mDb.rawQuery("select DISTINCT c from t_asv where b=" + booknumber, new String[]{});
Update:
Its better to use the PreparedStatement / how to use as mentioned by #patrick-hollweck
Writing code like this leaves your app wide open to a sql injection vulnerability and is generally considered a very bad practice
UPDATE: PROBLEM FIXED -
The ActionBar was covering the first item on the list.
SOLUTION: Android AppBarLayout overlaps listview
In my program, I am retrieving data from the database and displaying it using List View.
However, the first row elements are always skipped in the process and the display begins from the second row.
public void displaydata(){
Cursor res = myDb.getAllData();
lv = (ListView) findViewById(R.id.idListView);
if(res.getCount() == 0){
//show message
return;
}
ArrayList<String> buffer = new ArrayList<>();
while(res.moveToNext()){
buffer.add(res.getString(1));
};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,buffer);
lv.setAdapter(adapter);
}
How do I make it display from the first row?
Any help is appreciated, thanks.
EDIT: I have tried all suggested answers of using a 'do-while' and a 'for loop', all of which give the same result.
Try changing
while(res.moveToNext()){
buffer.add(res.getString(1));
};
to
Edit: change the while so it increments after:
do {
buffer.add(res.getString(1));
} while (cursor.moveToNext());
Personally, I would recommend a CursorAdapter when using a database.
lv = (ListView) findViewById(R.id.idListView);
String from = { COLUMN_NAME };
int[] to = { android.R.id.text1 };
SimpleCursorAdapter adapter =
new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1,
myDb.getAllData(),
from, to);
lv.setAdapter(adapter);
Try out this this code may be useful for fetching data from db using cursor.
public ArrayList<BasicInfo> getFetchBasicInfo() {
ArrayList<BasicInfo> data = new ArrayList<BasicInfo>();
String sql = "select * from basic_info;
Cursor c = fetchData(sql);
if (c != null) {
while (c.moveToNext()) {
String FirstName = c.getString(c.getColumnIndex("first_name"));
String LastName = c.getString(c.getColumnIndex("last_name"));
String Sabcription = c.getString(c
.getColumnIndex("salutation_id"));
data.add(new BasicInfo(FirstName, LastName));
}
c.close();
}
return data;
}
I have encountered a problem in my Android application. I want to retrieve all values of a column, but I am only getting one of the values. I have tried everything, but I could still not find a solution. Here is my code in my database:
public Cursor returnAllColumns() {
Cursor cursor = mDb.query(FTS_VIRTUAL_TABLE,
new String[] {KEY_ROWID,
KEY_NAME,
KEY_CUSTOMER, PROTEIN, TOTAL_CARB}
, null, null, null, null, null);
if (cursor != null) {
cursor.moveToNext();
}
return cursor;
}
Here is my code in another class where it shows a toast with all the values.
mDbHelper = new DBAdapter(DatabaseFiller.this);
mDbHelper.open();
Cursor c = mDbHelper.returnAllColumns();
String protein = c.getString(c.getColumnIndexOrThrow("protein"));
Toast.makeText(getApplicationContext(), protein, Toast.LENGTH_SHORT).show();
All I am getting is Protein = 0. What I should be getting is 0, 0, 0, 0, 0, 0,.... I don't know what I am doing wrong here. In my ListView, I got it right. It worked perfectly there. Here is my ListView code:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
cursor = (Cursor) mListView.getItemAtPosition(position);
//mListView.setItemChecked(position, true);
// Get the state's capital from this row in the database.
String name = cursor.getString(cursor.getColumnIndexOrThrow("customer"));
String caloriescursor = cursor.getString(cursor.getColumnIndexOrThrow("name"));
String totalfat = cursor.getString(cursor.getColumnIndexOrThrow("address"));
String satfatcursor = cursor.getString(cursor.getColumnIndexOrThrow("city"));
String state = cursor.getString(cursor.getColumnIndexOrThrow("state"));
String zipCode = cursor.getString(cursor.getColumnIndexOrThrow("zipCode"));
And that returns a Toast with a bunch of values. Any help regarding this problem would be appreciated.
In getAllColumns(), your query statement is correct. It does in fact fetch all columns. The if statement that follows simply points it to the first result. Then you are returning the cursor while it is pointed to the first result. You should take out the if statement because it doesn't do anything useful.
When trying to show the toast, you want something like this:
Cursor c = mDbHelper.returnAllColumns();
ArrayList<String> protein = new ArrayList<>();
while (c.moveToNext()) {
protein.add(c.getString(c.getColumnIndexOrThrow("protein")));
}
Toast.makeText(getApplicationContext(), TextUtils.join(", ", protein), Toast.LENGTH_SHORT).show();
You need to loop over the cursor if the cursor is returning more than one row, and build your output in the loop.
Keep calling c.moveToNext() until it returns false.
I had the same problem until I did this:
if (!cursor.moveToFirst()) {
Log.d(LOG_TAG, "=== cursor not moveToFirst() ===");
return null;
}
Log.d(LOG_TAG, "=== reading cursor of getAll() ===");
Log.d(LOG_TAG, String.valueOf(cursor));
List<Trip> trips = new ArrayList<>();
while (!cursor.isAfterLast()) {
trips.add(cursorToTrip(cursor));
cursor.moveToNext();
}
The cursor.moveToNext() will never check the first element. So I check in the course is not in the last one and then I add the object and move to the next one.
That's it! :)
I am developing an Android application where I search for records which are created after a given date. My code is some thing like this
public List<NPRMember> IncrementalData(String LastDtTime) {
List<NPRMember> results = new ArrayList<NPRMember>();
SQLiteDatabase db=getMyReadableDatabase();
String lastdt="datetime("+LastDtTime+")";
Cursor cursor = null;
try{
cursor = db.query(TABLE_NAME_NPR, new String[] { KEY_FULLNAME, KEY_FATHERNAME,
KEY_RCRD_SOURCE,KEY_RCRD_CRN_DATE},KEY_RCRD_CRN_DATE + ">? AND "+KEY_RCRD_SOURCE+">?",
new String[]{lastdt, "0"}, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
NPRMember nprmem = cursorToMemberDetails(cursor);
results.add(nprmem);
cursor.moveToNext();
}
}catch(Exception e){
Log.e(APP_NAME, "An error occurred while searching for "+LastDtTime+": "+e.toString(), e);
}finally{
if(cursor!=null && !cursor.isClosed()){
cursor.close();
}
}
return results;
}
The query does not return any value, although I have at least one record with KEY_RCRD_CRN_DATE 2013-07-25 18:59:19
The LastDtTime passed as parameter has value 2013-07-25 14:46:03.
One interesting thing is if I run the query at SQLite command prompt it returns the deisred record.
SELECT fullname, fathername, .... rcrdsource, rcrdcrtndate FROM nprmembers WHERE rcrdcrtndate>'2013-07-25
14:46:03' AND rcrdsource>0;
Any help would be appreciated.
Thanks
The parameter value (in lastdt) is wrong.
What you want is the string 2013-07-25 18:59:19, but you are actually using the string datetime(2013-07-25 18:59:19).
The letter d comes after 2, so no record matches.
Change the initialization of lastdt to:
String lastdt=LastDtTime;
I have this code in one of my activity's onCreate Method
GetNews newsReporter = new GetNews(getApplicationContext());
try{
News[] allNews = newsReporter.getAllNews();
Log.d("News Count", String.valueOf(allNews.length));
String[] timestamps = new String[allNews.length];
String[] texts = new String[allNews.length];
for(int i=0;i<allNews.length;i++)
{
// timestamps[i] = allNews[i].getNewsTime();
texts[i] = allNews[i].getNewsText();
// Log.d("TimeStamp", timestamps[i]);
Log.d("Text", texts[i]);
}
}catch(Exception e){
Log.e("Error News", e.toString());
}
News Count Displays 6 in Logcat, which means News[] is not null.
But I receive NullPointerException on Line texts[i] = allNews[i].getNewsTime();
this is my News Class
public class News {
private int id;
private String timestamp;
private String text;
public News(int i,String t, String ti)
{
this.id=i;
this.text = t;
this.timestamp = ti;
}
public String getNewsTime()
{
return this.timestamp;
}
public String getNewsText()
{
return this.text;
}
}
P.S. News is stored in a SQLitedatabase, when i pulled the database from my DDMS, it contains all 6 rows with valid values none of them is null.
Edit:
This is my GetAllNews Method
public News[] getAllNews(){
SQLiteDatabase db = ConMan.OpenDBConnection();
try{
Cursor cursor = db.query(News_Table, Columns, null, null, null, null, null);
if(cursor!=null)
{
cursor.moveToFirst();
}
News[] allNews = new News[cursor.getCount()];
int i =0;
while(cursor.isLast()){
allNews[i] = new News(Integer.parseInt(cursor.getString(0)),
cursor.getString(1),cursor.getString(2));
cursor.moveToNext();
i++;
}
db.close();
ConMan.close();
return allNews;
}catch(Exception e)
{
Log.e("News DB Errors", e.getMessage());
}
return null;
}
The problem is in the newsReporter.getAllNews() method. Looks like it is returning the array without the value initialized.
News[] allNews = newsReporter.getAllNews();
Meaning,
allNews.length might get you some value. But at each index, you are missing the value or at least one or more of the indexes are missing the value in the array.
Do the printing like below to see if you have values
for (News news : allNews)
System.out.println(news);
Looks like it is not going into the following block at all.
while(cursor.isLast()){
allNews[i] = new News(Integer.parseInt(cursor.getString(0)),
cursor.getString(1),cursor.getString(2));
cursor.moveToNext();
i++;
}
Check whether cursor.isLast() method is returning true to get into this loop.
texts[i] = allNews[i].getNewsText();
Most possibly, allNews[someIndex] is null. when called getnewsText() on null throws NPE.
best test is to output allNews[i] or check if it isnull.
System.out.println(allNews[i]==null)
An array of size 6 can have 6 null references. Print each of your News objects in allNews, I bet 10 Obamas that at least one position in the array is null.
You are saying that allNews[] is not null, so it must be that News[] contains a null, so that allNews[i].getNewsText() throws the exception.