如何在android中更新值更新的特定行

时间:2013-02-28 17:29:41

标签: android sqlite cursor

我正在使用SQLite数据库。每次有1或2行值更新时,表中会有持续更新。

例如:现在TABLE1中有20行,某些行值已更新..

我们能否知道在TABLE1中哪些行已更新?

我有解决方案,但性能对我很重要。 Cursor使用选择所有行的select查询注册数据观察者,当有更新时,我检索整个20行的更新值,进行编码。因此,如果有100行我需要循环所有这对于低端设备来说是一项繁琐的工作。

请协助解决方案,了解如何使用游标在Android中的表中检索更新的行。

3 个答案:

答案 0 :(得分:9)

如果您可以更改表,则添加TIMESTAMP类型的新列'modified_time'。每当更新行时更新此列。

现在,当您想知道哪些行已更新时,请运行此SQL查询:

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

此查询的结果给出了最新更新的所有行的ID。

修改 正如您在评论中提到的那样“... 服务器将数据推送到具有更改值的表。我需要获取更新值并更新到其他表”,最好的选择是创建一个在DB中触发,它将根据第一个表上的更新更新第二个表。这是方法。

假设服务器将数据推送到“table1”,并且您希望监视更新的行。创建另一个表2(或使用现有表),它将自动更新。

现在,按如下方式创建一个Trigger:

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

当然你的table2会有所不同,但想法是你可以使用trigger自动插入或更新table2中的行。您可以参考这些SO帖子了解更多详情:

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

Using SQLite Trigger to update "LastModified" field

示例应用 我已经创建了一个示例应用程序,以根据您描述的场景演示在Android应用程序中使用Trigger。您可以在此处下载Eclipse项目 - trigger_example_eclipse_project.zip

简而言之,示例应用程序有一个产品表,它接收产品价格的更新。因此,我们创建了另一个更新表,该表将通过触发器基于 product 表上的更新自动更新。

有一个用于通过EditText字段和Button模拟产品表上的更新的UI。为了显示最近的更新,我们有一个ListView,它使用Cursor从 updates 表中获取数据。

这里有一些来自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) {
    }

}

答案 1 :(得分:3)

您可以保留一个类似LAST_UPDATE_TIME的列,该列会在更新时使用当前时间进行更新。

然后,您只需查询LAST_UPDATE_TIME>所有行。所需的时间。

如果您无法更改表格,是否可以创建具有相同列的新表格?然后,您可以在两个表中进行更新,并在需要时从新表中获取值,并在完成后从新表中删除它们。

答案 2 :(得分:1)

如果您正确实现了ContentProvider,则插入或更新可能会返回该行的ID。

这有点复杂,但请查看Google's IOSchedule app查看提供商合同类,查看会议室合同中的类和插入或更新方法中提供者的“房间”案例 您将看到将返回一个Uri,在此设计方法中,最后一个元素(在最后一个斜杠之后)是插入/更新的行的 id

我这种方法可以帮助您,并且您可以了解Google的源代码以完成您的工作(我发现它有点难以理解)