在Android SQLite中 - 创建,如果主键不存在,则更新关联值

时间:2015-08-01 08:00:24

标签: android sqlite

我一直在努力学习如何实现标题中提到的功能,但我似乎无法弄明白。

我遇到过“INSERT OR IGNORE”的提及,但还没有看到使用它的工作解决方案,甚至找不到它的内部工作的有用解释。

所以我希望这里的某个人可以帮助我构建一个如何实现它的例子,最重要的是它的工作原理。我几乎选择了一个硬编码的解决方案来进行查询和相应的代码再次查询。但是为了保持低查询并更好地理解我希望学习如何在sqlite通信中解决问题。

2 个答案:

答案 0 :(得分:2)

在您的情况下,

OR IGNORE可能不是正确的构造。 OR IGNORE告诉SQLite不要对冲突行执行操作。它不会更新现有行。

但是,还有OR REPLACE,仅适用于UNIQUEPRIMARY KEY违规行为:

INSERT OR REPLACE INTO map (key, value) VALUES (1, 'AA');

(1, ?)替换任何行(1, 'AA')

在Android中,您可以通过insertWithOnConflict()(感谢@laalto获取指针)或通过自定义语句访问此功能:

<强> insertWithOnConflict()

int key;
String value;
SQLiteDatabase db;

try {
    ContentValues insertValues = new ContentValues();
    insertValues.put("key", key);
    insertValues.put("value", value);
    db.insertWithOnConflict(
        "map", 
        null,
        insertValues,
        SQLiteDatabase.CONFLICT_REPLACE
    );
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

自定义声明

SQLiteStatement stmt = db.compileStatement(
    "INSERT OR REPLACE INTO map (key, value) VALUES (?, ?);"
);   
stmt.bindLong(0, key);
stmt.bindString(1, value);
try {
    stmt.executeInsert();
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

这也可以用于根据已有值的计算来写入新值。例如,要将现有值增加1或 - 如果该值不存在 - 请插入新值:

SQLiteStatement stmt = db.compileStatement(
    "INSERT OR REPLACE INTO map (key, value) VALUES (
        ?,
        COALESCE((SELECT value + 1 FROM map WHERE key = ?), ?)
    )
);   
stmt.bindLong(0, key);
stmt.bindLong(1, key);
stmt.bindString(2, value);

如果(key, value)不存在,则会将key写入数据库。如果存在key,则会将value的现有key增加1。

但是,将它拆分为更新和插入查询可能更简单,更快捷,只有在更新失败时才运行插入。

答案 1 :(得分:0)

使用此方法进行对象插入。首先它尝试更新对象,但如果它在数据库中不存在则插入开始。

public void insertNewObject (<T> object){    //replace <T> by object type
        try {
                if(updateObject(object) == 0)
                    database.insert(TABLE_NAME, null, createContentValues(object));
            }
        }
        catch (Exception exc){
            exc.printStackTrace();
        }
    }

更新方法:

public long updateObject(<T> object){
        return database.update(TABLE_NAME, createContentValues(object), db.KEY_ID + "=" + object.getId(), null);
    }

db.KEY_ID是一个字符串 - 列名称,其id为

createContentValues方法:

 private ContentValues createContentValues(<T> object) {
        ContentValues values = new ContentValues();
        values.put(db.KEY_ID, object.getId());
        values.put(db.KEY_NAME, object.getName());
        //with other objects fields follow same principle
        return values;
    }

databaseSQLiteDatabase对象。