I'm new in android. I'm using SQLite database to store data. I have 2 column in this database which are containing unique data for each user.
The problem is when user will get an update, then the update will override the personal data. I want to update the database except 2 columns.
Here is my Initialize Database:
INSERT INTO WORDS (_id, unlocked,solved,score,word,letters,image,suggestion) VALUES (1,1,0,0,'example','example','pics/example.png','example');
As you can see, the 'solved' and 'score' has 0 values. I don't want to update these values. So I don't want to drop the entire database before the update, I would like to keep those 2 values, and make sure the update is not override those data.
Use like this
UPDATE table_name SET column_name1='value', column_name2 = 'value1' WHERE condition_column='value'
You can check it with weather DB table contains that user id or not, if not then do insert query as you are doing
If record found, just do updateQuery:
UPDATE WORDS set unlocked = 1, word = 'example',letters = 'example',image ='pics/example.png',suggestion='example' WHERE _id=1;
I have to say, you need to research, because this tag it's very trivial. So I recommend you to read more about.
this could be:
DatosSQLiteHelper usdbh = new DatosSQLiteHelper(this, "myDatabase", null, 1);
SQLiteDatabase db = usdbh.getWritableDatabase();
if(db != null)
{
//add all atributes for update
ContentValues registre = new ContentValues();
registro.put("myvar1", "value1");
registro.put("myvar2", "value2");
registro.put("myvar3", "value3");
int numcol = db.update("mytable", register, "_id_="+1, null);
if (numcol == 1)
{
Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();
}
}
Related
In my project, I use SQL (SQLite since its android) to save my data.
I encountered some odd problem:
In my application, I have three tabs and in order to know which data belong to which tab I have in my chart a column for each tab. the number in the column (Integer) represent if and how many of that data suppose to be in this tab.
So, when the tab initialized, it reads from the chart, and using the relevant column, it can tell which data needs to be read and how many.
When I retrieve data from the server (the database of the server is not related to the problem at hand), I check if the data is new or that I already have a similar one in my SQL DB. If its new, I add it to the SQL chart and put 1 in the relevant column. If it already exists, it checks if the data in the SQL is updated (it update the data if necessary) and add 1 to the relevant column (the same column it puts 1 in it in case the data is not in the SQL DB).
now here's my problem:
when it reads from the SQL DB to see the number in the column, so it can add 1 to it and then update the chart, it always return 1 regardless the actual number that in the column in that moment (I know its not really 1 because when I read from the DB in the same column from other places in my app it does read the actual number).
Since in other places in my app it doesn't happen I tried to see what is the difference between the places but I did not find anything wrong (the only difference is that I used WritableDatabase instead of just ReadableDatabase in that time but that should not be an issue as far as I know, at least not in such case).
the code where the problem occurs (the problem is with COL_CART):
writable = db.getWritableDatabase();
Cursor cursor = writable.query(
ShopContract.ShopChart.TABLE_NAME,
new String[]{ShopContract.ShopChart.COL_NAME, ShopContract.ShopChart.COL_PRICE, ShopContract.ShopChart.COL_PIC, ShopContract.ShopChart.COL_CART},
ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",
null,
null,
null,
null
);
if(cursor.moveToFirst()){
//check if the data match, if not, replace.
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_NAME)).equals(product.getName())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_NAME,product.getName());
update(values);
}
if(cursor.getDouble(cursor.getColumnIndex(ShopContract.ShopChart.COL_PRICE)) != product.getPrice()){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PRICE,product.getPrice());
update(values);
}
if(!cursor.getString(cursor.getColumnIndex(ShopContract.ShopChart.COL_PIC)).equals(product.getPicture())){
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_PIC,product.getPicture());
update(values);
}
//check how many there are already in cart (already in the cursor) and update it to be ++
Log.d(TAG, "run: the number in col_cart is: " + cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)));
int inCart = cursor.getInt(cursor.getColumnIndex(ShopContract.ShopChart.COL_CART)) + 1; // because of the new product we just added
Log.d(TAG, "run: inCart = " + inCart);
ContentValues values = new ContentValues();
values.put(ShopContract.ShopChart.COL_CART,inCart);
Log.d(TAG, "run: change cart");
update(values);
edit:
here is the update method code (the writable is being initialized in the code above):
private SQLiteDatabase writable;
private void update(ContentValues values){
writable.update(ShopContract.ShopChart.TABLE_NAME, values, ShopContract.ShopChart.COL_PROD_ID + " = '" + product.getProd_id() +"'",null);
}
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.
I have written the following code to update some information in a database using SQLite. The idea is to update a value (userAverageTime) in case the entry already exist, or make a new record if the entry does not yet exist.
Here is the code:
public void updateTableLevelsAverageTime(DatabaseOperations dop, LinkedList<Level> levels) {
SQLiteDatabase SQ = dop.getWritableDatabase();
String selection = KEY_NUMBERS + " = ?";
for (Level level: levels) {
String[] args = {level.toString()};
ContentValues cv = new ContentValues();
cv.put(KEY_AVERAGE_TIME, level.getAverageTime());
int result = SQ.update(TABLE_LEVELS, cv, selection, args);
if (result == 0) {
//If the entry doesn't exist, it must be a new level... thus add it with 0 as userseconds
ContentValues cv2 = new ContentValues();
cv2.put(KEY_NUMBERS, level.toString());
cv2.put(KEY_AVERAGE_TIME, level.getAverageTime());
cv2.put(KEY_USER_TIME, 0);
SQ.insert(TABLE_LEVELS, null, cv2);
Log.d("Database operations", "Row added");
}
else {
Log.d("Database operations", "Row updated");
}
}
SQ.close();
}
(KEY_*** are column names that are defined elsewhere in the code)
I was wondering if this was the best approach, though. The code takes quite some time to run.
I have read somewhere that if you want to update data you can do this batch-wise. But can you do this as well when you want to update only if a record exists and when you want to add the record if it doesn't exits?
You can use a REPLACE INTO command as you would use an INSERT INTO one, in order not to have to check if the record exists and execute the corresponding UPDATE or INSERT INTO command.
SQLite will first delete the row (if existing) and then insert it newly.
Therefore you can write an execSQL() instruction which uses the REPLACE INTO command where you are currently executing a query and then deciding which command to execute next.
The REPLACE INTO will help you skipping all that logic.
I find it really useful.
I've a situation in sqlite that make you an example: My table has two fields,"_id" and "_score" . I have a record with _id=1, _score=10. I want to update this row to 5 number more than the current value(10). in SQL i can do it simple like:
Update my_table set _score = _score + 5 where _id = 1
but in sqlite I have these that I don't know how can fix it to what I want :
ContentValues values = new ContentValues();
values.put("_score", my_value);
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
int id = db.update(MY_TABLE,values,"_id = ?",new String[]{String.valueOf(my_id)});
and the Other problem is the returned value. I think in above example I give
id = 1
for 1 row effected. but I want to know that: Is there any way to retrieve the value of updated column(in my example I want to give "15"). Some thing like in SQL server that we fetch from
"##ROWCOUNT" or "##fetch_status"
Hope to describe it well. thanks.
Android's update() function can set only fixed values.
To execute your SQL statement, you have to use execSQL():
db.execSQL("Update my_table set _score = _score + 5 where _id = 1");
In SQLite, the UPDATE statement does not return any data (except the count of affected rows). To get the old or new data, you have to execute a SELECT separately.
For your first problem about updating the score value try this:
ContentValues values = new ContentValues();
values.put("_score", my_value);
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
int id = db.update(my_table, values, _id + " = ?",
new String[] { String.valueOf(my_id) });
}
I would like to create a FIFO table in order to save only the most 50 recent infomations by deleting the oldest elements when a new infomation arrives. I can do it by manipulating ID in the table but I don't think it is the best solution. Any idea of doing it well?
Instead of checking for date time, sorting your items, and whatnot, you can just assume that the first row in your table is the last to be inserted.
In your Content Provider's insert(Uri uri, ContentValues cv), before doing your db.insert call, you can first query the number of items on that table using getCount() and delete the first row if count>50. Then proceed with your insert call.
You dont need to play with IDs in order to create a FIFO logic. The best would be to add another column as DATETIME in your table which automatically inserts current time-stamp that will help you to select records in ascending order with respect to this column. Your new column should be something like:
DateAdded DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
Make sure when ever you insert new record, you must do a COUNT check of total records in this table and if necessary delete the oldest record with respect to DateAdded. Moreover, you can make use of LIMIT and/or MAX in your select-query when it comes to delete the oldest record.
Add a datetime type column to your table if it doesn't contain it yet and set it to 'now' on each insert. Then on each insert select all with limit set to 50 sorted by date. Choose the last item and run a delete query to delete everything older than this last item.
is it must to use sqlite? can you use file handling? you can use simple Queue object and save it to file.
Here is what I did for a list of transactions, and it works okay. When inserting a new entry I check if the count is above 50, if so, I just delete the very last entry:
// Adding new transaction
public void addTransaction(Transaction transaction) {
SQLiteDatabase db = this.getWritableDatabase();
if(getTransactionsCount() > 50){
List<Transaction> allTransactions = getAllTransactions();
Transaction oldestTransaction = allTransactions.get(allTransactions.size()-1);
deleteTransaction(oldestTransaction);
}
ContentValues values = new ContentValues();
values.put(KEY_TRANSACTION_UID, transaction.getUID());
values.put(KEY_TRANSACTION_AMOUNT, transaction.getAmount());
values.put(KEY_TRANSACTION_IS_ADD, transaction.getIsAdd());
// Inserting Row
db.insert(TABLE_TRANSACTIONS, null, values);
db.close(); // Closing database connection
}
And getAllTransactions() returns the list in descending order (based on the id primary key):
// Getting All Transactions
public List<Transaction> getAllTransactions() {
List<Transaction> transactionList = new ArrayList<Transaction>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TRANSACTIONS + " ORDER BY " + KEY_TRANSACTION_ID + " DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Transaction transaction = new Transaction();
transaction.setID(Integer.parseInt(cursor.getString(0)));
transaction.setUID(cursor.getString(1));
transaction.setAmount(cursor.getString(2));
transaction.setIsAdd(cursor.getString(3));
// Adding contact to list
transactionList.add(transaction);
} while (cursor.moveToNext());
}
// return contact list
return transactionList;
}