简体   繁体   English

遍历SQLite表的行以更新ID

[英]Iterating through rows of SQLite table to update ids

I'm working on an Android app with an SQLite database. 我正在使用带有SQLite数据库的Android应用程序。

I have a table called REMINDER (with 2 columns: REMINDER_ID and REMINDER_VALUE) and I am allowing the user to delete any record from that table. 我有一个名为REMINDER的表(带有2列:REMINDER_ID和REMINDER_VALUE),并且允许用户从该表中删除任何记录。 For reasons that would take a bit to explain, I need the REMINDER_ID column to always have sequential numbers. 出于某些原因需要解释,我需要REMINDER_ID列始终具有顺序号。 So, if the user deletes row 2, I need to eliminate that gap, so row 3 becomes row 2, row 4 becomes row 3, etc.. 因此,如果用户删除第2行,则需要消除该间隙,因此第3行变为第2行,第4行变为第3行,依此类推。

I wrote a method in my DBHelper class to do the update of the db whenever a row is deleted, but I'm not sure whether this is the best way to do it. 我在DBHelper类中编写了一个方法,以便每当删除一行时就更新数据库,但是我不确定这是否是最好的方法。

Below is the method to delete a row from the REMINDER table. 下面是从REMINDER表中删除行的方法。 As you can see, before I delete the row, I check whether it's the last row or not, because if it is I don't have to bother updating the ids. 如您所见,在删除行之前,我会检查它是否是最后一行,因为如果是最后一行,则不必费心更新id。

public void deleteReminder(int reminder_id){
    SQLiteDatabase db = this.getWritableDatabase();

    String selectQuery = "SELECT MAX(" + COLUMN_REMINDER_ID + ") FROM " + REMINDERS_TABLE;
    Cursor cursor = db.rawQuery(selectQuery, null);
    int maxId = cursor.getInt(cursor.getColumnIndex(COLUMN_REMINDER_ID));

    db.delete(REMINDERS_TABLE, COLUMN_REMINDER_ID + "= ?", new String[] {String.valueOf(reminder_id)});

    if (reminder_id != maxId){
        updateRemindersIds();
    }

    cursor.close();
    db.close();
}

This is the method used for updating the id's: 这是用于更新ID的方法:

    public void updateRemindersIds(){

        SQLiteDatabase db = this.getWritableDatabase();
        String selectQuery = "SELECT * FROM " + REMINDERS_TABLE;
        Cursor cursor = db.rawQuery(selectQuery, null);
        ContentValues values = new ContentValues();
        int new_id = 1;

        if(cursor.moveToFirst()){
            do{
                values.put(COLUMN_REMINDER_ID, new_id);
                int old_id = cursor.getInt(cursor.getColumnIndex(COLUMN_REMINDER_ID));
                db.update(REMINDERS_TABLE, values, COLUMN_REMINDER_ID + "= ?", new String[] {String.valueOf(old_id)});
                new_id++;

            } while (cursor.moveToNext());
        }

    }
}

I haven't gotten to the point of testing it yet, but even if it works, I'm wondering whether there is a better way of doing this? 我还没有达到测试的目的,但是即使它可以工作,我也在想是否有更好的方法可以做到这一点? My reason for asking is because I don't have much experience. 我问的原因是因为我没有太多经验。

Thank you 谢谢

EDIT: creating a method that implements Joachim Isaksson's solution: 编辑:创建一种实现Joachim Isaksson解决方案的方法:

public void updateRemindersIds(){
    SQLiteDatabase db = this.getWritableDatabase();
    String updateQuery = "UPDATE " + REMINDERS_TABLE + " SET " + COLUMN_REMINDER_ID + " = (" +
                            "SELECT COUNT(*) + 1 FROM " + REMINDERS_TABLE + " r " +
                            "WHERE " + REMINDERS_TABLE + "." + COLUMN_REMINDER_ID + "> r." + COLUMN_REMINDER_ID + ")";

    db.execSQL(updateQuery);
    db.close();

}

I suppose this is correct for Android / Java / SQLite? 我想这对Android / Java / SQLite是正确的吗?

As long as they have unique reminder id's, you could renumber the items using a single update; 只要它们具有唯一的提醒ID,您就可以使用一次更新为项目重新编号。

UPDATE reminders SET reminder_id = (
  SELECT COUNT(*)+1
  FROM reminders r
  WHERE reminders.reminder_id>r.reminder_id
);

An SQLfiddle to test with . 要使用进行测试的SQLfiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM