3

I am using SQLite database. There is continuous update coming in to table, each time 1 or 2 row values get updated.

For example: Now there are 20 rows in TABLE1 some of the rows values gets updated..

Can we know which rows got updated in TABLE1 ?

I have solution but the performance matters to me. Cursor registers data-observer with a select query that selects all rows, when there is an update I retrieve entire 20 rows with updated values, do my coding. So if there are 100 rows I need to loop all which is a tedious task for low end devices.

Kindly assist with a solution, that how to retrieve the updated row in a table in Android using a cursor.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Rockin
  • 723
  • 4
  • 25
  • 51
  • There are many Android developer support sites on the Internet. You may have better luck with one in a language more comfortable for you. I have several such sites listed at http://www.andglobe.com. – CommonsWare Mar 06 '13 at 14:39
  • Can you post the code where you are updating the database? – Shajeel Afzal Mar 17 '13 at 18:31

3 Answers3

9

If it is possible for you to alter the table then add a new column 'modified_time' of type TIMESTAMP. Update this column whenever a row is updated.

Now when you want to know which rows got updated, run this SQL query:

select _id from table2 where modified_time = (select max(modified_time) from table2)

The result of this query gives the id of all rows which got updated latest.

Edit: As you have mentioned in your comment "... server pushes the data to table with changed values.i need take the update values and update to other table", the best option for you is to create a Trigger in the DB which will update the second table based on the updates on first table. Here is the approach.

Let's say server pushes the data to 'table1' and you want to monitor the rows updated. Create another table2 (or use existing) which will automatically get updated.

Now, create a Trigger as follows:

CREATE TRIGGER trigger1 AFTER UPDATE ON table1
 BEGIN
  update table2 SET modified_time = datetime('now') WHERE row_id = old._id;
 END;

Of course your table2 will differ but the idea is that you can insert or update rows in table2 automatically using trigger. You may refer these SO posts for more details:

Does sqlite3 support a trigger to automatically update an 'updated_on' datetime field?

Using SQLite Trigger to update "LastModified" field

Sample Application: I have created a sample application to demonstrate the use of Trigger in an Android application based on the scenario you have described. You can download the Eclipse project here - trigger_example_eclipse_project.zip

In brief, the sample application has a product Table which receives updates on product price. So we create another updates Table which will automatically get updated based on the updates on product Table through a Trigger.

There is an UI to simulate updates on product Table by an EditText field and a Button. And to display the recent updates we have a ListView wich uses a Cursor to fetch data from updates Table.

Here some relevant code snippet from DbHelper.java

public class DbHelper extends SQLiteOpenHelper {

    public static final String TABLE1 = "product";
    public static final String TABLE2 = "updates";

    public static final String COL_ID = "_id";
    public static final String COL_NAME = "name";
    public static final String COL_PRICE = "price";
    public static final String COL_MODIFIED_TIME = "modified_time";

    public static final String KINDLE = "Kindle";

    private static final String SQL_CREATE_TABLE1 = 
            "CREATE TABLE product (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER);";

    private static final String SQL_CREATE_TABLE2 = 
            "CREATE TABLE updates (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER, modified_time TIMESTAMP);";

    private static final String SQL_CREATE_TRIGGER = 
            "CREATE TRIGGER price_update AFTER UPDATE OF price ON product"+
            "   BEGIN" +
            "       INSERT INTO updates(name,price,modified_time) VALUES(old.name,new.price,datetime('NOW'));"+
            "   END;";

    public DbHelper(Context context) {
        super(context, "sampledb", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_TABLE1);
        db.execSQL(SQL_CREATE_TABLE2);
        db.execSQL(SQL_CREATE_TRIGGER);

        ContentValues cv = new ContentValues();
        cv.put(COL_NAME, KINDLE);
        cv.put(COL_PRICE, 99);
        db.insert(TABLE1, null, cv);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
    }

}
Community
  • 1
  • 1
appsroxcom
  • 2,821
  • 13
  • 17
  • sorry, its not answer to my question,i want to get the updated row values from database... – Rockin Feb 28 '13 at 17:52
  • 1
    Please see my edited answer. The query is not optimized. Perhaps there is a better way of writing the query. But you get the idea. – appsroxcom Feb 28 '13 at 19:18
  • Thanks for the info...I also have a doubt..if 1st rows gets update pn 11.36(time) and second row gets updated on 11.37. when i send a query will it get both of the updated values or only the 11.37. Also sorry i can't alter the table...since server pushes the data to table with changed values.i need take the update values and update to other table.. – Rockin Mar 01 '13 at 02:25
  • I assumed multiple rows are updated through the query so you pass one modified_time value to the UPDATE query. But if rows are updated at different time then you will have to provide a range for ex. modified_time > current_time - delay. Is it possible for you to create another table or trigger in the DB? – appsroxcom Mar 01 '13 at 02:54
  • your suggestions is right .but i need someother way...something like when update comes in table....it shouls have callback didchangecursor return the cursor row with updated data. – Rockin Mar 04 '13 at 06:50
  • 1
    Is it possible for you to create Trigger in the DB? – appsroxcom Mar 04 '13 at 07:25
  • How can i get the update of table1,trigger in front-end ,so that i can get the data from table1 and manipulate and put it in table 2 – Rockin Mar 06 '13 at 04:09
  • "A database trigger is procedural code that is automatically executed in response to certain events on a particular table or view in a database." - Wikipedia. So the database automatically does it for you. You just need to create the Trigger and specify that on update of any row in table1, update/insert a row in table2 (as i shown in the SQL). Just execute the SQL for creating Trigger after you create the Tables in onCreate(SQLiteDatabase db) method of your DbHelper (i.e. SQLiteOpenHelper). – appsroxcom Mar 06 '13 at 16:56
  • Please import the sample eclipse project (see my edited answer) and check whether it fits your requirements. – appsroxcom Mar 15 '13 at 05:59
  • ok thanks ...i think this is the maximum answer that i can get...i will give the bounty...Hope like iphone something like didchangeobject callback will come – Rockin Mar 19 '13 at 05:55
  • Welcome and thank you for the bounty ... IMHO a combination of Trigger and CursorLoader is the best what Android can offer. http://stackoverflow.com/questions/7182920/what-are-the-benefits-of-cursorloaders Good luck with your project. – appsroxcom Mar 19 '13 at 13:14
3

You could keep a column like LAST_UPDATE_TIME, which is updated with the current time when updating.

Then you can just query for all rows where the LAST_UPDATE_TIME > required time.

If you cant alter the table, can you create a new table with the same columns ? Then you can update in both tables and when required fetch the values from the new table and delete them only from the new table when you are done with them.

user2138983
  • 1,313
  • 9
  • 15
1

If you implement your ContentProvider correctly an insert or update could return you the id of the row.

It is a bit complicated, but take a look at Google's IOSchedule app review the Provider and Contract class, look at Room class in the Contracts and at the "Room" cases in the Provider in the insert or update method.
You will see that an Uri will be returned, in this design approach the last element (after the last slash) is the id of the inserted/updated row.

I this approach could help you, and that you can understand Google's source code to get your work done (I found it a bit tricky to understand)

Nickolaus
  • 4,785
  • 4
  • 38
  • 60