I am going to fetch some rows with specific tag in android Sqlite.
The problems are
I got 15 with cursor.getCount(); but 13 rows retrieved.
the 13 rows just repeat last row data
here is my code
public ArrayList<HashMap<String, String>> getTodo(String tag) {
ArrayList<HashMap<String,String>> arList = new ArrayList<HashMap<String,String>>();
HashMap<String, String> todo = new HashMap<String, String>();
String selectQuery = "SELECT * FROM " + TABLE_NAME + " WHERE "
+ COLUMN_TAG + " = ?";
String[] args={tag};
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, args);
// Move to first row
cursor.moveToFirst();
System.out.println(cursor.getCount());
if (cursor.getCount() > 0) {
do {
todo.put(COLUMN_ID, cursor.getString(cursor.getColumnIndex(COLUMN_ID)));
todo.put(COLUMN_FROM, cursor.getString(cursor.getColumnIndex(COLUMN_FROM)));
todo.put(COLUMN_TO, cursor.getString(cursor.getColumnIndex(COLUMN_TO)));
todo.put(COLUMN_TITLE, cursor.getString(cursor.getColumnIndex(COLUMN_TITLE)));
todo.put(COLUMN_TAG, cursor.getString(cursor.getColumnIndex(COLUMN_TAG)));
arList.add(todo);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
// return todo
return arList;
}
Please help. Thanks
You are using the same todo object for all rows, so you end up with lots of references to the same object.
Create a new one for each row in the loop:
Cursor cursor = db.rawQuery(selectQuery, args);
try {
while (cursor.moveToNext()) {
HashMap<String, String> todo = new HashMap<String, String>();
todo.put(...);
...
arList.add(todo);
}
finally {
cursor.close();
}
It's better to make the todo's you want to acquire into objects
public class Todo {
public String id, from, to, title, tag;
//setters and getters (not necessary)
}
public ArrayList<MyData> getTodo(String tag) {
ArrayList<MyData> arList = new ArrayList<MyData>();
String selectQuery = "SELECT * FROM " + TABLE_NAME + " WHERE "
+ COLUMN_TAG + " = ?";
String[] args={tag};
try {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, args);
// Move to first row
if (!cursor.moveToFirst())
return arList;
do {
Todo todo = new Todo();
todo.id = cursor.getString(cursor.getColumnIndex(COLUMN_ID));
todo.from = cursor.getString(cursor.getColumnIndex(COLUMN_FROM));
todo.to = cursor.getString(cursor.getColumnIndex(COLUMN_TO));
todo.title = cursor.getString(cursor.getColumnIndex(COLUMN_TITLE))
todo.tag = cursor.getString(cursor.getColumnIndex(COLUMN_TAG));
arList.add(todo);
} while(cursor.moveToNext());
cursor.close();
db.close();
return arList;
}
finally {
cursor.close();
db.close();
}
}
You keep putting new strings to an already created hashmap, but you keep using the same keys, and therefore, many entries get replaced. The Todo object keeps your code readable. You should also check if the cursor can jump to the first entry (which makes a getCount call unnecessary)
Related
i am trying to add some items from database to my list but when i run the application i see that the list is empty.
this is what i did to add items to a list
car_size = dbHelper.getSize("cars"); // getSize is a method that count items in database
Random random = new Random();
int cars_random = random.nextInt(car_size);
List<String> myList = dbHelper.read_added_names("cars"); // and this line should add items from database to the list
if(myList!= null && myList.size() > 0) {
textView.setText(myList.get(truth_random));
}else {
Toast.makeText(activity.this, "" + myList.size(), Toast.LENGTH_SHORT).show();
} // here i can see that the size of my list is 0 and it's empty
I'm sure the methode that should read database (here i named it read_aded_names) works fine
public List<String> read_added_names (String subject){
String selectQuery;
List<String> list = new ArrayList<String>();
if (subject.equals("*")) {
selectQuery = "SELECT * FROM " + TABLE_NAME1;
}else {
selectQuery = "SELECT * FROM " + TABLE_NAME1 + " WHERE " + COLUMN_SUBJECT + " = '" + subject+" '";
}
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
list.add(cursor.getString(1));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return list;
}
Query contains space after subject variable making it "cars " instead of "cars". This can be the issue.
I have this:
public void addNewNote(Note n) {
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, n.getNote_title());
values.put(COLUMN_TEXT, n.getNote_text());
values.put(COLUMN_FK, n.getNote_ForeignKey()); //this column is integer type
values.put(COLUMN_PT, String.valueOf(n.getNote_PersonType())); //this column is char type
SQLiteDatabase db = this.getWritableDatabase();
db.insert("tbl_Notes",null, values);
}
as my add method, as I traced it, the record is added successfully. but when I try to get my note with below code, findNote always returns null and cnt is always 0.
public Note findNote(int note_id){
String query = "select * from tbl_Notes"; // where " + COLUMN_ID + " = " + note_id;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
int cnt = cursor.getCount();
Note N = new Note();
if (cursor.moveToFirst()) {
cursor.moveToFirst();
N.setNote_title(cursor.getString(1)); //title column
N.setNote_text(cursor.getString(2)); //text body column
N.setNote_ForeignKey(Integer.parseInt(cursor.getString(3))); //foreign key column
N.setNote_PersonType(cursor.getString(4).charAt(0)); //person type column
cursor.close();
}else {
N = null;
}
return N;
}
and here is my onClick which fires addNewNote:
Note myNote = new Note(
txt_Title.getText().toString(),
foreignKey,
personType,
txt_Body.getText().toString()
);
tbl_notes.addNewNote(myNote);
what am I doing wrong?!
Below is the code I'm using to grab all results stored in an SQLite table. The problem I am having is that it is only returning a single row when I know there are 21 rows in the DB.
public HashMap<String, String> fetchResults(String TABLE_NAME, String sql) {
HashMap<String, String> table = new HashMap<String, String>();
if(sql == null)
sql = "";
String selectQuery = "SELECT * FROM " + TABLE_NAME + " " + sql;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String[] columns = null;
switch(TABLE_NAME ){
case "projects":
columns = dbTables.projectsColumns;
break;
}
// Move to first row
cursor.moveToFirst();
if (cursor.getCount() > 0) {
int n=1;
for(int i=0; i<columns.length; i++){
table.put(columns[i], cursor.getString(n));
n++;
}
}
//move to the next row
cursor.moveToNext();
cursor.close();
db.close();
// return user
Log.d(TAG, "Fetching " + TABLE_NAME + " from Sqlite: " + table.toString());
return table;
}
The db call is made within a fragment and look like this.
HashMap<String, String> projects = db.fetchResults(dbTables.TABLE_PROJECTS, null);
for (String key : projects.keySet()) {
if(key == "projectname"){
System.out.println("Key: " + key + ", Value: " + projects.get(key));
menuList.add(projects.get(key));
}
}
You are only retrieving one single row there:
// Move to first row
cursor.moveToFirst();
if (cursor.getCount() > 0) {
int n=1;
for(int i=0; i<columns.length; i++){
table.put(columns[i], cursor.getString(n));
n++;
}
}
You have to iterate the cursor to get all results:
// Move to first row
cursor.moveToFirst();
if (cursor.getCount() > 0) {
while(cursor.moveToNext()) {
for (int i = 0; i < columns.length; i++) {
table.put(columns[i], cursor.getString(i));
}
}
}
But your table would list all the column values of every row. If you want to have a table with row-entries, define a class for storing the column values.
I am unsure on what the cursor.movetonext() method is because I have never used it, but I would just been using a method like this:
public static ResultSet createRS(String Query,String Server) {
// Create a variable for the connection string.
String connectionUrl = "jdbc:sqlserver://"+Server+"\\SQLExpress;databaseName=Schedule;" +
"integratedSecurity=true;";
// Declare the JDBC objects.
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// Establish the connection.
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
// Create and execute an SQL statement that returns a
// set of data and then display it.
String SQL = Query;
stmt = con.createStatement();
rs = stmt.executeQuery(SQL);
}
// Handle any errors that may have occurred.
catch (Exception e) {
e.printStackTrace();
}
return rs;
}
With the result set you can just do this:
try {
while (rs.next()) {
current=Double.parseDouble(rs.getString(currentColumn));
}
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
Thanks to all who answered. I have found a function that works for perfectly.
public Cursor getAllRows(String TABLE_NAME, String sql){
String selectQuery = "SELECT * FROM " + TABLE_NAME + " " + sql;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor != null){
cursor.moveToFirst();
}
return cursor;
}
I am working on an app which contains an Android SQLite database. I add and delete rows in this database. When I delete my row, it is based on the ROWID. But I found out, that despite I delete the row, the ROWID remains. So for example if I have 3 rows in my database and delete the 2nd row, my third row will not change to 2 it remains 3. Then if I add a row, it will be 4.
So my question is, how to do that when I delete a row, and add a new one then the number of the added row would equal to the deleted row. So for example if I delete the first row, than the database will show me next to the other rows 1,2,3... and not 2,3,4...
Sorry, maybe it is a little bit complicated, but I hope it makes sense.
Here is my code:
public HotOrNot open() throws SQLException{
ourHelper = new DbHelper(ourContext);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close(){
ourHelper.close();
}
public long createEntry(String name, String hotness) {
// TODO Auto-generated method stub
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_HOTNESS, hotness);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getData() {
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_HOTNESS};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iName = c.getColumnIndex(KEY_NAME);
int iHotness = c.getColumnIndex(KEY_HOTNESS);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + c.getString(iRow) + " " + c.getString(iName) + " " + c.getString(iHotness) + "\n";
}
return result;
}
public String getName(long l) throws SQLException{
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_HOTNESS};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + l, null, null, null, null);
if(c != null){
c.moveToFirst();
String name = c.getString(1);
return name;
}
return null;
}
public String getHotness(long l) throws SQLException{
// TODO Auto-generated method stub
String[] columns = new String[]{ KEY_ROWID, KEY_NAME, KEY_HOTNESS};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + l, null, null, null, null);
if(c != null){
c.moveToFirst();
String hotness = c.getString(2);
return hotness;
}
return null;
}
public void updateEntry(long lRow, String mName, String mHotness) throws SQLException{
// TODO Auto-generated method stub
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(KEY_NAME, mName);
cvUpdate.put(KEY_HOTNESS, mHotness);
ourDatabase.update(DATABASE_TABLE, cvUpdate, KEY_ROWID + "=" + lRow, null);
}
public void deleteEntry(long lRow1) throws SQLException{
// TODO Auto-generated method stub
ourDatabase.delete(DATABASE_TABLE, KEY_ROWID + "=" + lRow1, null);
}
}
I know that it can't be done using ROWID, because it is unique for each row.
Could you please write the code how to solve this problem, because I am beginner in Android and also in SQLite.
Thanks in advance
SQLite keeps track of the largest ROWID that a table has ever held
using the special SQLITE_SEQUENCE table.
You can update SQLITE_SEQUENCE table-
UPDATE SQLITE_SEQUENCE SET seq = <n> WHERE name = <table_name>
n is the rowid - 1
Similar question.
Here is the schema:
SQL query is:
SELECT * from unjdat where col_1 = "myWord";
i.e., I want to display all columns for a row whose col_1 is myWord.
int i;
String temp;
words = new ArrayList<String>();
Cursor wordsCursor = database.rawQuery("select * from unjdat where col_1 = \"apple\" ", null); //myWord is "apple" here
if (wordsCursor != null)
wordsCursor.moveToFirst();
if (!wordsCursor.isAfterLast()) {
do {
for (i = 0; i < 11; i++) {
temp = wordsCursor.getString(i);
words.add(temp);
}
} while (wordsCursor.moveToNext());
}
words.close();
I think the problem lies with the looping. If I remove the for loop and do a wordsCursor.getString(0) it works. How to loop to get all columns?
Note:
col_1 is never null, any of the col_2 to col_11 may be null for some rows.
All columns and all rows in the table are unique.
This is how it should be
Cursor cursor = db.rawQuery(selectQuery, null);
ArrayList<HashMap<String, String>> maplist = new ArrayList<HashMap<String, String>>();
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
HashMap<String, String> map = new HashMap<String, String>();
for(int i=0; i<cursor.getColumnCount();i++)
{
map.put(cursor.getColumnName(i), cursor.getString(i));
}
maplist.add(map);
} while (cursor.moveToNext());
}
db.close();
// return contact list
return maplist;
Edit User wanted to know how to fill ListView with HashMap
//listplaceholder is your layout
//"StoreName" is your column name for DB
//"item_title" is your elements from XML
ListAdapter adapter = new SimpleAdapter(this, mylist, R.layout.listplaceholder, new String[] { "StoreName",
"City" }, new int[] { R.id.item_title, R.id.item_subtitle });