Sqlite UPDATE with parameterised IN (...) clause [duplicate] - android

This question already has answers here:
IN clause and placeholders
(9 answers)
Closed 10 years ago.
In my app I'm working with sqlite database - and I hit a strange issue.
I have a table that looks like this:
_id field1 field2 status
--- ------ ------ ------
1 value value ...
2 value value ...
...
At one place, I need to update some rows to set them to another status, so I'm trying
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("status", STATUS_SENT);
Set<Integer> ids = datasource.getCompletedIds();
String idparam = TextUtils.join(",", ids);
int cnt = db.update(TABLE_ORDERS, cv, "_id in (?)", new String[] { idparam });
Log.d("db", "updated " + cnt + " rows");
db.close();
However nothing gets updated - and db.update returns 0. What am I missing?

I'm not happy recommending not using parameters, but it this case, it's actually easier than formatting all those ? markers (and with plain integers, just as safe):
db.update(TABLE_ORDERS, cv, "_id IN (" + idparam + ")", null);

Unfortunately you must list one insertion character ? for each id in your Set...
A popular fix is to write a quick utility to add the appropriate number of ?s based on the Set's size.

Related

Why none proposed solution is not working when I try to update a record in SQLite Database?

I am a novice user,I am trying to update a record with some fields and nothing special. I noticed! that this may be answered a lot of times but none of the proposed answers is working and I dont know where to check in my code to find the solution. I have the following :
public int updateUser(User user) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(U_ID, user.getId());
values.put(U_NAME, user.getName());
values.put(U_EMAIL, user.getEmail());
values.put(U_ZIP, user.getZip());
values.put(U_CREATED_AT, user.getCreated_at());
int res = db.update("login_user", values, "U_ID" + "=?", new String[] {String.valueOf(user.getId())});
return res;
}
I have tried
int res = db.update("login_user", values, "U_ID" + " = ?", new String[] {String.valueOf(user.getId())});
int res = db.update("login_user", values, "U_ID" + "=?", new String[] {(UserId)});
int res = db.update(MYTABLE, values, U_ID + "=?", new String[] {String.valueOf(user.getId())});
I increased my Database version to make it empty I saved a new record so
My Data are not null, but I get as res=0 and not an expected res=1 and with no errors
What I am doing wrong and where to look?
herein lies your problem
I increased my Database version to make it empty
assuming your database is empty, then you should use the insert method instead. updating an empty table will not have any effects because the WHERE condition in the update statement will always return false.
db.insertWithOnConflict (String table,
null, //nullColumnHack
values,
SQLiteDatabase.CONFLICT_REPLACE);
this will create an entry if the userId is not found, or replace the existing userId row if there is a conflict
The response from the Sqlite Update method is the number of rows updated.
If the record exists in the DB then it will return 1 (or more)
If you've updated the DB number all the records are delted - so verify the record exists 1st.
If it's returning 0 then I suspect you don't have the record in the DB in the first place - so 0 records are updated.
If you're expecting 1 - then first check if the record exists, via ADB - see this answer on how to check the contents of your DB.

Query error in SQLite [duplicate]

This question already has answers here:
Update table using rawQuery() method does not work
(5 answers)
Closed 6 years ago.
I've tried this code to update all my values in column sync to 0...
How can I solve this issue?
public boolean updatesync()
{
SQLiteDatabase db=this.getWritableDatabase();
db.rawQuery("update patients set sync = '0'",null);
return true;
}
This code is not working. I need to change the entire column value of sync to 0. How can I do that? I've found this code as working when searching, but it's not working for me. How can I solve that?
Please help.
Use execSQL() instead of rawQuery().
rawQuery() just compiles the SQL but does not execute it until the returned Cursor is moved. execSQL() both compiles and executes the SQL.
for update value in Sqlite , try this one
public int updateName(string name,String Id){
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + Id, null) > 0;
}
*** Note ***
KEY_NAME= Column name (value will update),
DATABASE_TABLE =Table name ,
KEY_ROWID = Column name (value will update depends on this column name)

Delete specific record in sqlite table based on two criteria: _id and column

I have created a sqlite table for my android app, this table has 5 columns and multiple rows, the columns being: _id, column1, column2, column3, column4.
I want to delete a specific record, for instance the record stored in column3 corresponding to _id (in a different class are the getters and setters, for this I've named the class "TableHandler")
I guess that I'm a bit confused, following is what I was planning, but for column3 I'm not sure what should be the argument, I just want to delete whatever is in that column position corresponding to _id
public void deleteValueColumn3(TableHandler value){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, KEY_ID + " = ? AND " + KEY_COLUMN3 + " = ?",
new String[] {String.valueOf(value.getID()), ?????????);
db.close();
}
The ???????? is that I'm stuck there, maybe the whole method needs to be rewritten, I would appreciate your input.
Thanks
If you want to delete the whole record, just use the _id of the record in delete method, because that is the primary key for your table and therefore is unique. If you'd rather keep the record, you con always use the SQLiteDatabase.update method, specifying null as the new value that will replace column3 value; check out that column3 declaration has no NOT NULL tag, otherwise that could easily throw exception at you.
SQLite does not allow you to delete columns for a specific row.
You can only delete ROWS of data (delete the row that has the column _ID = 1).
Here's a quick tutorial on SQL.
How about updating that column with a null value, rather than using delete()?
ContentValues cv = new ContentValues();
cv.putNull(KEY_COLUMN3);
db.getWritableDatabase().update(
TABLE_NAME,
cv,
KEY_ID + "=?",
new String[]{String.valueOf(keyIdValue)});

Android SQLite Repeated Elements

I have an issue with SQLite on android. Right now, I'm pulling a JSON object from a server, parsing it, and putting each sub-object in a Table with things such as the Name, Row_ID, unique ID, etc. using this code:
public void fillTable(Object[] detailedList){
for(int i=0;i<detailedList.length;++i){
Log.w("MyApp", "Creating Entry: " + Integer.toString(i));
String[] article = (String[]) detailedList[i];
createEntry(article[0], article[1], article[2], article[3], article[4], article[5]);
}
}
createEntry does what it sounds like. It takes 6 strings, and uses cv.put to make an entry. No problems.
When I try to order them however, via:
public String[] getAllTitles(int m){
Log.w("MyApp", "getTitle1");
String[] columns = new String[]{KEY_ROWID, KEY_URLID, KEY_URL, KEY_TITLE, KEY_TIME, KEY_TAGS, KEY_STATE};
Log.w("MyApp", "getTitle2");
Cursor c = ourDatabase.query(DATABASE_TABLENAME, columns, null, null, null, null, KEY_TIME);
Log.w("MyApp", "getTitle3");
String title[] = new String[m];
Log.w("MyApp", "getTitle4");
int i = 0;
int rowTitle = c.getColumnIndex(KEY_TITLE);
Log.w("MyApp", "getTitle5");
for(c.moveToFirst();i<m;c.moveToNext()){
title[i++] = c.getString(rowTitle);
Log.w("MyApp", "getTitle " + Integer.toString(i));
}
return title;
}
Each entry actually has many duplicates. I'm assuming as many duplicates as times I have synced. Is there any way to manually call the onUpgrade method, which drops the table and creates a new one, or a better way to clear out duplicates?
Secondary question, is there any way to order by reverse? I'm ordering by time now, and the oldest added entries are first (smallest number). Is there a reverse to that?
If you don't want duplicates in one column then create that column with the UNIQUE keyword. Your database will then check that you don't insert duplicates and you can even specify what should happen in that case. I guess this would be good for you:
CREATE TABLE mytable (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
theone TEXT UNIQUE ON CONFLICT REPLACE
)
If you insert something into that table that already exists it will delete the row that already has that item and inserts your new row then. That also means that the replaced row gets a new _id (because _id is set to automatically grow - you must not insert that id yourself or it will not work)
Your second question: you can specify the direction of the order of if you append ASC (ascending) or DESC (descending). You want DESC probably.
Cursor c = ourDatabase.query(DATABASE_TABLENAME, columns, null, null, null, null, KEY_TIME + " DESC");

Android SQL update table

I am upgrading my database to add another column. What I am trying to do is (after the column is added in onUpgrade) this method is called from the main activity for each table (3 were upgraded). The method is supposed to replace all of the blanks in the new column with "1".
The code runs fine, stepping through, boolean test is true every time but when I open the table to view the data, the entire column is blank. The weird part is, my rowId numbers are incrementing every time. It starts out with 3 rows with rowIds of 1,2,3 respectively. After my code runs once, they now have rowIds of 4,5,6 respectively.
Can anyone help me out? KEY_ROWID is just my auto rowId number. KEY_MODE is just "mode" for column title. If I run through debugging it, the three rows I have show up in the code (it runs through the while loop 3 times).
public void checkBlanks(String table) {
Cursor cursor = mDb.query(table, new String[] {KEY_ROWID, KEY_MODE}, null, null, null, null, null);
while (cursor.moveToNext()) {
int modeCol = cursor.getColumnIndexOrThrow(KEY_MODE);
if (cursor.isNull(modeCol)) {
int rowId = cursor.getInt(cursor.getColumnIndexOrThrow(KEY_ROWID));
ContentValues args = new ContentValues();
args.put(KEY_MODE, 1); // replace the blank space with a "1"
boolean test = mDb.update(table, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
cursor.close();
}
Instead of manually looping through the rows, why don't you just leverage the power of SQL and update ALL of the rows in one call? E.g.
mDb.execSQL("UPDATE " + table + " SET " + KEY_MODE + " = 1;");
Since it's so simple, you can do this right in your onUpgrade() method.
You could have done that much easier:
1.) During onUpgrade(): "add column newcolumn default 1". This would add a new column with all newcolumns containing 1.
2.) onUpgrade() is already run: update table set newcolumn=1: Without a WHERE clause the whole table is affected.
There's not need to walk thru all rows.
What you want to do requires an SELECT...FOR UPDATE OF/UPDATE...WHERE CURRENT OF. I didn't do that with SQLite, so I don't know if this is supported.
In your situation (onUpgrade is already run) use 2.)

Categories

Resources