SQLite 删除一行并将所有其他行向上移动

时间:2021-06-16 18:52:59

标签: java sqlite android-sqlite

这可能是不可能的,但我似乎找不到明确的答案。当我删除数据库中的一行时,我希望另一行的 ID 基本上向上移动,所以如果我删除了第 2 行,那么第 3 行的 ID 将变为 2。这可能吗?我正在使用 AUTOINCREMENT 所以不知道是否有相反的情况?

这是我的完整 SQLite 代码。

public class ProfileDatabaseHelper extends SQLiteOpenHelper {

    public static final String PROFILE_TABLE = "PROFILE_TABLE";
    public static final String PROFILE_ID = "ID";
    public static final String PROFILE_IMAGE = "PROFILE_IMAGE";
    public static final String RADAR_DATA_ONE = "DATA_ONE";
    public static final String RADAR_DATA_TWO = "DATA_TWO";
    public static final String RADAR_DATA_THREE = "DATA_THREE";
    public static final String RADAR_DATA_FOUR = "DATA_FOUR";
    public static final String RADAR_DATA_FIVE = "DATA_FIVE";
    public static final String RADAR_DATA_SIX = "DATA_SIX";

    public ProfileDatabaseHelper(@Nullable Context context) {
        super(context, "profiles.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTableStatement = "CREATE TABLE " + PROFILE_TABLE + " (" + PROFILE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + PROFILE_IMAGE + " TEXT, "
                + RADAR_DATA_ONE + " INT, " +  RADAR_DATA_TWO + " INT, " + RADAR_DATA_THREE + " INT, " + RADAR_DATA_FOUR + " INT, " + RADAR_DATA_FIVE
                + " INT, " + RADAR_DATA_SIX + " INT)";

        db.execSQL(createTableStatement);


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public boolean updateData(Integer id,String profilePhoto,Integer dataOne, Integer dataTwo, Integer dataThree, Integer dataFour, Integer dataFive, Integer dataSix){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues contentValues=new ContentValues();
        contentValues.put(PROFILE_ID,id);
        contentValues.put(PROFILE_IMAGE,profilePhoto);
        contentValues.put(RADAR_DATA_ONE,dataOne);
        contentValues.put(RADAR_DATA_TWO,dataTwo);
        contentValues.put(RADAR_DATA_THREE,dataThree);
        contentValues.put(RADAR_DATA_FOUR,dataFour);
        contentValues.put(RADAR_DATA_FIVE,dataFive);
        contentValues.put(RADAR_DATA_SIX,dataSix);
        db.update(PROFILE_TABLE,contentValues,"ID = ?",new String[] {id.toString()});
        return true;

    }


    public boolean addOne(ProfileModel profileModel){

        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(PROFILE_IMAGE, profileModel.getProfilePhoto());
        cv.put(RADAR_DATA_ONE, profileModel.getDataOne());
        cv.put(RADAR_DATA_TWO, profileModel.getDataTwo());
        cv.put(RADAR_DATA_THREE, profileModel.getDataThree());
        cv.put(RADAR_DATA_FOUR, profileModel.getDataFour());
        cv.put(RADAR_DATA_FIVE, profileModel.getDataFive());
        cv.put(RADAR_DATA_SIX, profileModel.getDataSix());

        long insert = db.insert(PROFILE_TABLE, null, cv);
        if (insert == -1){
            return false;
        }
        else{
            return true;
        }
    }

    public Cursor alldata(){
        SQLiteDatabase dataBaseHelper = this.getWritableDatabase();
        Cursor cursor = dataBaseHelper.rawQuery("select * from PROFILE_TABLE ", null);
        return cursor;
    }

    public boolean delete(int id) {
        SQLiteDatabase db = this.getWritableDatabase();
        String queryString = "DELETE FROM " + PROFILE_TABLE + " WHERE " + PROFILE_ID + " = " + id;
        //deleting row
        Cursor cursor = db.rawQuery(queryString, null);
        if(cursor.moveToFirst()){
            return true;
        }
        else {
            return false;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

<块引用>

我正在使用 AUTOINCREMENT 所以不知道是否有相反的情况?

第一个 AUTOINCREMENT 不会增加 rowid(或其别名)值,而是一个约束(规则),表明 rowid 必须大于任何曾经分配过的 (如果 sqlite_sequence没有在 SQLite 对表的管理之外进行修改)

它使用 INTEGER PRIMARY KEY 允许自动分配一个值,通常比当前最高的 rowid 值大 1。但是,如果值 + 1 大于可能的最大值 (9223372036854775807),则:-

  • 使用 AUTOINCREMENT 会出现 SQLITE_FULL 错误。
  • 如果没有 AUTOINCREMENT,则会尝试查找未使用的数字。

极不可能到达/使用 (9223372036854775807)。

AUTOINCREMENT 效率较低,因为它必须记录有史以来分配的最高 rowid,并且通过使用 sqlite_sequence 表来完成。在 SQLite 文档中它说:-

<块引用> <块引用>

AUTOINCREMENT 关键字会增加额外的 CPU、内存、磁盘空间和磁盘 I/O 开销,如果不是绝对需要,应该避免使用。通常不需要。

将 rowid 或其别名用于任何其他用途是一个非常糟糕的主意,而不是用于从另一行唯一标识一行的预期用途,例如在形成关系、更新或删除行时。

  • 例如如果按 ID 列以外的另一列或多列对数据进行排序 (ORDER BY) 会怎样?该 ID 对应用程序用户是否有意义?

但是,尽管不推荐这样做,但以下内容可以满足您的要求:-

private void rationaliseCol1Values() {
    ContentValues cv = new ContentValues();
    Cursor csr = mDB.query(PROFILE_TABLE,null,null,null,null,null,PROFILE_ID + " ASC");

    int rowcount = csr.getCount();
    long expected_id = 1;
    long current_id;
    String where_clause = PROFILE_ID + "=?";
    String[] args = new String[1];

    while (csr.moveToNext()) {
        current_id = csr.getLong(csr.getColumnIndex(PROFILE_ID));
        if (current_id != expected_id) {
            cv.clear();
            cv.put(PROFILE_ID,expected_id);
            args[0] = String.valueOf(current_id);
            mDB.update(PROFILE_TABLE,cv,where_clause,args);
        }
        expected_id++;
    }
    csr.close();
    // Now adjust sqlite_sequence
    where_clause = "name=?";
    args[0] = PROFILE_TABLE;
    cv.clear();
    cv.put("seq",String.valueOf(rowcount));
    mDB.update("sqlite_sequence",cv,where_clause,args);
}
相关问题