Update row in SQlite database by row position in android - android

I have database which contains "date" column and "item" column.
I want that user could update specific row in the database.
I trying to do it with update method in SQLiteDatabase class.
My problem is that i dont know how to make update method find exactly the row i want.
I saw some example that use it with parameters from one word.
like this:
ourDatabase.update(tableName, cvUpdate, rowId + "=" + item , null);
My problem is that i want to update the row that have specific item and date. so the name of the item alone is not enough.
I tried this code below but its didnt work, hope youll can help me.
public void updateEntry(String item, String date) throws SQLException{
String[] columns = new String[]{myItem, myDate};
Cursor c = ourDatabase.query(tableName, columns, null, null, null, null, null);
long position;
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(date, myDate);
cvUpdate.put(item, myExercise);
int itemAll = c.getColumnIndex(myItem);
int dateAll = c.getColumnIndex(myDate);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
if (c.getString(itemAll).equals(myItem) && c.getString(dateAll).equals(myDate))
{
position = c.getPosition();
break;
}
}
ourDatabase.update(tableName, cvUpdate, rowId + "=" + position , null);
}

First, the columns String[] is supposed to contain column names, such as "_ID", or whatever are the column names you have used. Given that you compare the content of the column myItem with the object myItem, I assume there is a confusion somewhere here.
Secondly, rowId and position are different things in SQL, especially if you delete rows, as the row id usually is autoincrement, and especially since your query is not explicitely sorted. Replacing c.getPosition() by c.getLong(c.getColumnIndex(ID_COLUMN)) would make more sense.
Thirdly, sql is nice because you can query it. For example, rather than get all items and loop to find the matching date and item, you can :
String whereClause = ITEM_COLUMN + " = ? and " + DATE_COLUMN + " = ?";
String[] whereArgs = new String[] { item, date };
Cursor c = ourDatabase.query(tableName, columns, whereClause, whereArgs, null, null, null);
instead of your for loop.
Forthly, you can even make the query in the update :
String whereClause = ITEM_COLUMN + " = ? and " + DATE_COLUMN + " = ?";
String[] whereArgs = new String[] { item, date };
ourDatabase.update(tableName, cvUpdate, whereClause, whereArgs);
Extra tip: use full caps variable names for contants such as column names, it help with readability.

Related

Can't extract integer from cursor after preforming sqlite query in Android

I'm working on an small android app that maintains a small database of tools which I lend out to other people.
As part of the app, I am incorporating an sqllite database, where I am having a bit of trouble performing queries and working with cursors once the queries have been executed.
The code in question is as follows:
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_NAME };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns,
selection, selectionArgs, null, null, null, null);
return Integer.parseInt(cursor.getString(3));
The contract for the database is as follows:
public class ToolStatisticContract {
public static final class ToolStatisticEntry implements BaseColumns {
public static final String TABLE_NAME = "tooltable";
public static final String COLUMN_TOOL_NAME = "toolName";
public static final String COLUMN_LIFESPAN = "lifespan";
public static final String COLUMN_USAGE = "usageTime";
}
}
I am essentially trying to extract out the value from COLUMN_USAGE, which seems to be producing errors with regards to parsing the value to an integer. The value in the COLUMN is actually an integer typecasted as a String from a previous segment of code, so I'm fairly certain the error is encompasssed with the code snippets above.
Thanks again in advance for all your help!
The code in question is as follows
The net SQL statement is something like:
SELECT toolName FROM tooltable WHERE toolName = ?
And there is no column with index 3, since you are only returning 1 column.
You need to:
Have usageTime in your column list (COLUMNS)
Move the Cursor to a valid row (as it initially is positioned before the first row)
Pass getInteger() the value that lines up with COLUMNS to retrieve usageTime
You could use the following. This uses null instead of columns, which will get all columns (i.e. resolves to SELECT * FROM table). It checks that a row has been returned and only then does it try to get the data. It also closes the cursor (you should close a cursor when done with it). It uses cursor.getInt() to get the integer value rather than convert it from a string to int. It assumes that you'll only get 1 row (if no rows then 0 will be returned).
int returnvalue = 0;
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_NAME };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, null,
selection, selectionArgs, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
returnvalue = cursor.getInt(2);
//or returnvalue = Integer.parseInt(cursor.getString(2));
}
cursor.close();
return returnvalue;
Note! I haven't checked this just coded it from memory, so apologies for the odd mistake.
To do the above using specific columns then you could use:-
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_USAGE };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns,
selection, selectionArgs, null, null, null, null);
In which case the column index would be 0 (that is the index is according to the column's in the cursor). However it might be better to use, the following which gets the column index according to the column's name:-
cursor.getInt(cursor.getColumnIndex(COLUMN_USAGE);
The easiest way to read a single value from the database is to use a helper function that allows you to avoid having to handle cursor objects:
String query = "SELECT usageTime FROM tooltable WHERE toolName = ?";
String[] selectionArgs = { tool };
long returnvalue = DatabaseUtils.longForQuery(mToolDb, query, selectionArgs);

how to filter multiple data on multiple column sqlite database

i want to filter multiple data such as
id = "1,3,5" from columnid which is having 1 to 10 id
and another column such as name
name = "a,e,d" from name column of 10 records
and another criteria such as age
age = "21,23,20" from age column of 10 records from same table,
one example i got is
Cursor cursor = db.query("TABLE_NAME",new String[]{"ColumnName"}, "ColumnName=?",new String[]{"value"}, null, null, null);
which is just for one column but i want to get data from multiple column, can anyone help me?
try this working example,
Cursor cursor =
db.query(TABLE_DIARYENTRIES,
new String[] {},
STUDENT_ID + " IN ("+resultStudent+")"+ " AND " +CLASS_NAME + " IN ("+resultClass+")"
+ " AND " +SUBJECT_NAME + " IN ("+resultSubject+")"
null, null, null, null);
and your result string should be 'a','b','c'
I really like the way Google's example is structured. Because for noobies such as myself it makes it really clear what I am doing. And it is also more robust to SQL injections. Here is my modified version of the Google example:
//Column(s) I want returned
String[] projection = {"ColumnIWantReturned"};
//Column(s) I want to filer on
String selection = "FilterColumn1 IN (?) and FilterColumn2 IN (?, ?)";
String[] selectionArgs = {"ArgumentForFilterColumn1", "FirstArgumentForFilterColumn2", "SecondArgumentForFilterColumn2"};
Cursor cursor = db.query(
"MyTable", // The table to query
projection, // The array of columns to return (pass null to get all)
selection, // The columns for the WHERE clause
selectionArgs, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Log.d("this-is-a-test", cursor.getString(0));
cursor.moveToNext();
}
cursor.close();

how to retrieve a specific string data from sqlite database by using 2 string arguments?

this is my code used which i use for making method
String item = item1.getText().toString();
item = item.toLowerCase();
String date = getDate();
edited = new Datahelper(this);
edited.open();
String returnedprice = edited.getprice(item,date);
String returneddetail = edited.getdetail(item,date);
edited.close();
price.setText(returnedprice);
details.setText(returneddetail);
and this is my code of method that i am using for getting that string but here i dont know how to use the 2nd date string so that the string price that return is from a row that contains that item and that date.. please give me the code of how to do it..
public String getprice(String item ,String date) {
// TODO Auto-generated method stub
String[] columns = new String[]{KEY_ROWID,
KEY_CATEGORY,KEY_DATE,KEY_PRICE,KEY_DETAILS};
Cursor v =ourDatabase.query(DATABASE_TABLE, columns, KEY_CATEGORY + " ='" + item
+"'",null,null, null, null);
if(v!=null){
String price = v.getString(3);
return price;
}
return null;
}
public String getdetail(String item,String date) {
// TODO Auto-generated method stub
String[] columns = new String[]{KEY_ROWID,
KEY_CATEGORY,KEY_DATE,KEY_PRICE,KEY_DETAILS};
Cursor v =ourDatabase.query(DATABASE_TABLE, columns, KEY_CATEGORY + " ='" + item +
"'",null,null, null, null);
if(v!=null){
String detail = v.getString(4);
return detail;
}
return null;
}
So probably you want to use two arguments in select query so:
You can use two methods:
rawQuery()
query()
I will give you basic example for both cases.
First:
String query = "select * from Table where someColumn = ? and someDateColumn = ?";
Cursor c = db.rawQuery(query, new String[] {textValue, dateValue});
Explanation:
So i recommend to you use ? that is called placeholder.
Each placeholder in select statement will be replaced(in same order so first placeholder will be replaced by first value in array etc.) by values from selectionArgs - it's String array declared above.
Second:
rawQuery() method was easier to understand so i started with its. Query() method is more complex and has a little bit more arguments. So
columns: represents array of columns will be selected.
selection: is in other words where clause so if your selection is
KEY_COL + " = ?" it means "where " + KEY_COL + " = ?"
selectionArgs: each placeholder will be replaced with value from this
array.
groupBy: it's multi-row (grouping) function. more
about
having: this clause is always used with group by clause here is
explanation
orderBy: is clause used for sorting rows based on one or multiple
columns
Also method has more arguments but now you don't need to care about them. If you will, Google will be your friend.
So let's back to explanation and example:
String[] columns = {KEY_COL1, KEY_COL2};
String whereClause = KEY_CATEGORY " = ? and " + KEY_DATE + " = ?";
String[] whereArgs = {"data1", "data2"};
Cursor c = db.query("Table", columns, whereClause, whereArgs, null, null, null);
So whereClause contains two arguments with placeholder for each. So first placeholder will be replaced with "data1" and second with "data2".
When query is performed, query will look like:
SELECT col1, col2 FROM Table WHERE category = 'data1' AND date = 'data2'
Note: I recommend to you have look at Android SQLite Database and ContentProvider - Tutorial.
Also i recommend to you an usage of placeholders which provide safer and much more readable and clear solutions.
You should read any SQL tutorial to find out what a WHERE clause it and how to write it.
In Android, the selection parameter is the expression in the WHERE clause.
Your query could be written like this:
c = db.query(DATABASE_TABLE, columns,
KEY_CATEGORY + " = ? AND " + KEY_DATE + " = ?",
new String[] { item, date },
null, null, null);

passing parameter of _id and updating SQLitedatabase

I'm trying to update an SQLite table using the row id as my where statement. I'm getting the row _id from a row shown in a listview and passing to another activity with this statement:
Cursor cursor = (Cursor) nurseTableAdapter.getItem((int)id);
showAssignments.putExtra("Nurse", cursor.getInt(cursor.getColumnIndex("_id")));
The receiving activity receives the parameter:
nurse = extras.getString("Nurse");
and passes it as a parameter to my DbCommunicator class:
updateAssignments.updateNurseAssignments(listItemsArray, nurse);
and my DbCommunicator class does this with it:
public void updateNurseAssignments(String[] choices, String nurseId) {
// set parameter variables
//int nurseIdToInt = Integer.parseInt(nurseId);
//String strFilter = "_id=" + nurseIdToInt;
//String where = "_id=?";
String[] whereArgs = {String.valueOf(nurseId)};
Log.i(TAG, "value of whereArgs is " + whereArgs[0]);
// set content values
ContentValues cvUpdate = new ContentValues();
cvUpdate.put(KEY_FIRST_ASSIGNMENT, choices[0]);
cvUpdate.put(KEY_SECOND_ASSIGNMENT, choices[1]);
cvUpdate.put(KEY_THIRD_ASSIGNMENT, choices[2]);
cvUpdate.put(KEY_FOURTH_ASSIGNMENT, choices[3]);
cvUpdate.put(KEY_FIFTH_ASSIGNMENT, choices[4]);
cvUpdate.put(KEY_SIXTH_ASSIGNMENT, choices[5]);
// update database
sqldb.update(NURSE_TABLE, cvUpdate, KEY_NURSE_ROWID + "= ?", whereArgs);
}
I'm getting no errors, but the table is not updating. I've only found one similar example in Stack Overflow, and have tried to incorporate some of that here, but still having problems. Suggestions appreciated.

Content provider updating all rows

working on a content provider and I'm having an issue with it. When I try to update a certain row in the SQLite database through the content provider, it updates the column in all the rows, not just the row I specify. I know the CP is working because I can access it, populate a listview with it, and change the content of column, but never just one column.
Here is the relevant update method
public int update(Uri url, ContentValues values, String where,
String[] whereArgs) {
SQLiteDatabase mDB = dbHelper.getWritableDatabase();
int count;
String segment = "";
switch (URL_MATCHER.match(url)) {
case ITEM:
count = mDB.update(TABLE_NAME, values, where, whereArgs);
break;
case ITEM__ID:
segment = url.getPathSegments().get(1);
count = mDB.update(TABLE_NAME, values,
"_id="
+ segment
+ (!TextUtils.isEmpty(where) ? " AND (" + where
+ ')' : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
getContext().getContentResolver().notifyChange(url, null);
return count;
}
and here is the code I use to (try to) update it.
ContentValues mUpdateValues = new ContentValues();
mUpdateValues.put(ContentProvider.HAS, "true");
mUpdateValues.put(ContentProvider.WANT, "false");
mRowsUpdated = getContentResolver().update(Uri.parse(ContentProvider._ID_FIELD_CONTENT_URI
+ rowId), mUpdateValues, null, null);
and here is the URI
URL_MATCHER.addURI(AUTHORITY, TABLE_NAME + "/#", ITEM__ID);
Thanks, any help would be appreciated.
EDIT I have also tried
mRowsUpdated = getContentResolver().update(
ContentProvider._ID_FIELD_CONTENT_URI, mUpdateValues,
null, null);
and
mRowsUpdated = getContentResolver().update(
ContentProvider.CONTENT_URI, mUpdateValues,
null, null);
You are not specifying a WHERE clause, which is what is used to update only specific rows. The default behavior of content providers is to update all the rows, unless you specify conditions.
From the docs:
developer.android.com/reference/android/content/ContentResolver.html
Parameters
uri The URI to modify.
values The new field values. The key is the column name for the field. A null value will remove an existing field value.
where A filter to apply to rows before updating, formatted as an SQL WHERE clause (excluding the WHERE itself).

Categories

Resources