从文档中可以看出,插入或更新的语法是:INSERT OR REPLACE INTO <table> (<columns>) VALUES (<values>)
,我的问题是有合并以下内容的函数吗?
public long insert (String table, String nullColumnHack, ContentValues values)
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
还是必须使用准备好的SQL语句和rawQuery?
在Android中插入或更新的最佳做法是什么?
答案 0 :(得分:81)
我相信您在一步中询问如何插入新行或更新现有行。虽然这可以在this answer中讨论的单个原始SQL中实现,但我发现使用SQLiteDatabase.insertWithOnConflict()使用CONFLICT_IGNORE for conflictAlgorithm在Android中分两步完成此操作更容易。
ContentValues initialValues = new ContentValues();
initialValues.put("_id", 1); // the execution is different if _id is 2
initialValues.put("columnA", "valueNEW");
int id = (int) yourdb.insertWithOnConflict("your_table", null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
if (id == -1) {
yourdb.update("your_table", initialValues, "_id=?", new String[] {"1"}); // number 1 is the _id here, update to variable for your code
}
此示例假定表键为“_id”列设置,您知道记录_id,并且已经存在行#1(_id = 1,columnA =“valueA”,columnB =“valueB”) 。这是使用insertWithOnConflict与CONFLICT_REPLACE和CONFLICT_IGNORE
的区别当您尝试插入尚未存在的新行#2时,代码将仅在第一个语句insertWithOnConflict中执行SQL INSERT(即结果将为_id = 2,columnA =“valueNEW”,columnB = NULL)。
小心this bug导致SQLiteDatabase.CONFLICT_IGNORE在API10(可能是API11)上出现故障。我在Android 2.2上测试时,查询返回0而不是-1。
如果您不知道记录键_id或者您的条件不会产生冲突,您可以将逻辑反转为UPDATE或INSERT 。这将在UPDATE期间保留记录键_id或在INSERT期间创建新记录_id。
int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
上面的示例假定您只想在记录中更新时间戳值,例如。如果先调用insertWithOnConflict,INSERT将根据时间戳条件的不同创建新的记录_id。
答案 1 :(得分:41)
这是您的方法SQLiteDatabase.insertWithOnConflict()。了解它在sqlite
上引用this document的含义答案 2 :(得分:8)
SQLiteDatabase.replace()这样做,它基本上叫:
insertWithOnConflict(table, nullColumnHack, initialValues, CONFLICT_REPLACE);
太糟糕了,文档不是很清楚。
答案 3 :(得分:4)
您需要识别表格的列,使其成为一行。
实施例: _id,name,job,hours_worked
列是名称和作业,当您识别它时使用此方法:
private int getID(String name, String job){
Cursor c = dbr.query(TABLE_NAME,new String[]{"_id"} "name =? AND job=?",new String[]{name,job},null,null,null,null);
if (c.moveToFirst()) //if the row exist then return the id
return c.getInt(c.getColumnIndex("_id"));
return -1;
}
在你班上:
public void insertOrUpdate(String name, String job){
ContentValues values = new ContentValues();
values.put("NAME",name);
values.put("JOB",job);
int id = getID(name,job);
if(id==-1)
db.insert(TABLE_NAME, null, values);
else
db.update(TABLE_NAME, values, "_id=?", new String[]{Integer.toString(id)});
}
答案 4 :(得分:3)
SQLiteDatabase.replace()可能就是你要找的东西。我没有尝试过,但是文档说它返回了新插入的行的行ID ,所以它可能有效。
答案 5 :(得分:2)
我遇到了同样的问题,但我意识到当我的对象已经有一个ID它应该被更新,当它没有ID时它应该被插入所以这是我为解决问题所做的一步一步: / p>
1-你的对象getId使用Integer或初始化Id你认为合适的方式:这里是我的代码
public Integer getId() {
return id;
}
2-在将所有内容放入ContentValues后,检查方法中的ID以进行插入或更新:
if(myObject.getId()!= null ){
int count = db.update(TABLE_NAME,myContentValues,ID + " = ? ",
new String[]{String.valueOf(myObject.getId())});
if(count<=0){
//inserting content values to db
db.insert(TABLE_NAME, null, myContentValues);
}
} else {
db.insert(TABLE_NAME, null, myContentValues);
}
这里发生的是我检查Id是否存在我更新了那行但是如果update方法返回-1则表示没有带有该Id的行所以我插入了行,如果它没有Id我插入它。
希望这会有所帮助。
答案 6 :(得分:0)
怎么样? replaceOrThrow(String table,String nullColumnHack,ContentValues initialValues)
文档说...替换数据库中的行的便捷方法。 如果行尚不存在,则插入新行。
基本上它调用 insertWithOnConflict
答案 7 :(得分:0)
对我来说,如果您没有“ _id”(主键),那么所有方法都无效。
您应该先调用update,如果受影响的行为零,然后使用ignore将其插入:
blueback.wantsLayer = true
blueback.layer?.masksToBounds = true
blueback.layer?.cornerRadius = 50