You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在SQLite数据库同一行插入数据(避免新增行)

解决SQLite中同一DAYS值重复插入行的问题

我来帮你搞定这个问题!你现在遇到的核心问题是:当前的insertData方法只会执行插入操作,完全没判断DAYS值是否已经存在于数据库里,所以每次调用都会新增一行,而不是更新已有行。要实现「存在则更新,不存在则插入」的需求,我们可以用几种不同的方案,下面给你详细说明:

方案1:利用SQLite的INSERT OR REPLACE(简洁高效)

这个方案的前提是,你的表需要给DAYS列加上唯一约束,这样SQLite才能识别到冲突,进而替换现有行。

第一步:确保表结构有唯一约束

如果还没建表,建表时要加上UNIQUE(DAYS)

CREATE TABLE tasbeeh_table (
    DAYS TEXT UNIQUE,
    tasbeehName TEXT,
    count INTEGER
);

如果已经建表,可以通过ALTER TABLE添加约束(不过SQLite对ALTER TABLE支持有限,也可以直接重新建表迁移数据)。

第二步:修改插入方法为「插入或替换」

把原来的insert方法换成insertWithOnConflict,指定冲突策略为CONFLICT_REPLACE

public boolean insertOrUpdateData(String days, String tasbeehName, int count) {
    SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put("DAYS", days);
    contentValues.put("tasbeehName", tasbeehName);
    contentValues.put("count", count);

    // 当DAYS冲突时,替换现有行
    long result = sqLiteDatabase.insertWithOnConflict(
        "tasbeeh_table", 
        null, 
        contentValues, 
        SQLiteDatabase.CONFLICT_REPLACE
    );
    sqLiteDatabase.close();
    return result != -1; // 返回操作是否成功
}

⚠️ 注意:REPLACE会删除原有行再插入新行,如果你的表有自增ID这类列,ID会被重置;如果不想影响其他列,看下面的方案3。

方案2:先查询再判断(直观兼容旧版本)

如果不想修改表结构,或者需要更精细的控制,可以先查询数据库中是否存在该DAYS的行,存在则更新,不存在则插入:

public boolean insertOrUpdateData(String days, String tasbeehName, int count) {
    SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
    
    // 查询是否存在目标DAYS的行
    Cursor cursor = sqLiteDatabase.query(
        "tasbeeh_table", 
        new String[]{"DAYS"}, 
        "DAYS = ?", 
        new String[]{days}, 
        null, null, null
    );
    
    boolean isRowExists = cursor.moveToFirst();
    cursor.close();
    
    long result;
    if (isRowExists) {
        // 存在则更新指定列
        ContentValues contentValues = new ContentValues();
        contentValues.put("tasbeehName", tasbeehName);
        contentValues.put("count", count);
        result = sqLiteDatabase.update(
            "tasbeeh_table", 
            contentValues, 
            "DAYS = ?", 
            new String[]{days}
        );
    } else {
        // 不存在则插入新行
        ContentValues contentValues = new ContentValues();
        contentValues.put("DAYS", days);
        contentValues.put("tasbeehName", tasbeehName);
        contentValues.put("count", count);
        result = sqLiteDatabase.insert("tasbeeh_table", null, contentValues);
    }
    
    sqLiteDatabase.close();
    return result != -1;
}

方案3:使用SQLite的UPSERT语法(精准更新,推荐新版本)

如果你的Android API版本在26及以上(对应SQLite 3.24.0+),可以用更灵活的ON CONFLICT DO UPDATE语法,它只会更新你指定的列,不会替换整行:

public boolean insertOrUpdateData(String days, String tasbeehName, int count) {
    SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
    String sql = "INSERT INTO tasbeeh_table (DAYS, tasbeehName, count) VALUES (?, ?, ?) " +
                 "ON CONFLICT(DAYS) DO UPDATE SET tasbeehName = ?, count = ?";
    try {
        sqLiteDatabase.execSQL(sql, new Object[]{days, tasbeehName, count, tasbeehName, count});
        return true;
    } catch (SQLException e) {
        e.printStackTrace();
        return false;
    } finally {
        sqLiteDatabase.close();
    }
}

这个方案的优势是:即使表中有其他列,也不会被影响,只会更新你指定的tasbeehNamecount,比REPLACE更安全。

内容的提问来源于stack exchange,提问作者Al Walid Ashik

火山引擎 最新活动