Android SQLite插入或更新

在文档中可以看到插入或更新的语法是: 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中插入或更新的最佳做法是什么?

我相信你问的是如何插入新的行或更新您的现有行在一步。 虽然在这个答案中讨论过的单个原始SQL中可能会发生这种情况 ,但我发现在Android中使用SQLiteDatabase.insertWithOnConflict()使用CONFLICT_IGNORE for conflictAlgorithm的两步操作更容易。

 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 } 

这个例子假设table key被设置为列“_id”,你知道logging_id,并且已经有行#1(_id = 1,columnA =“valueA”,columnB =“valueB”)。 这是使用insertWithOnConflict和CONFLICT_REPLACE和CONFLICT_IGNORE的区别

  • CONFLICT_REPLACE将覆盖其他列中的现有值为空(即,columnB将变为NULL,结果将是_id = 1,columnA =“valueNEW”,columnB = NULL)。 你作为结果丢失了现有的数据,我没有在我的代码中使用它。
  • CONFLICT_IGNORE将会跳过你现有的第一行的SQL INSERT,并且你将在下一步SQL更新这一行,保留所有其他列的内容(即结果将是_id = 1,columnA =“valueNEW”,columnB =“ VALUEB“)。

当你试图插入新的第二行,但是这个代码只会在第一个语句insertWithOnConflict中执行SQL INSERT(即结果是_id = 2,columnA =“valueA”,columnB = NULL)。

当心这个错误导致SQLiteDatabase.CONFLICT_IGNORE在API10(可能是API11)上出现故障。 当我在Android 2.2上testing时,查询返回0而不是-1。

如果您不知道logging键_id或者您有一个不会产生冲突的条件,则可以将逻辑反转为UPDATE或INSERT 。 这将在UPDATE期间保持您的logging密钥_id或在INSERT期间创build新的logging_id。

 int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"}); if (u == 0) { yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE); } 

上面的例子假设你只是想更新logging中的时间戳记值。 如果先调用insertWithOnConflict,由于时间戳条件的差异,INSERT将创build新的logging_id。

这是你的方法SQLiteDatabase.insertWithOnConflict() 。 了解它在sqlite上引用这个文档是什么

SQLiteDatabase.replace()这样做,它基本上调用:

 insertWithOnConflict(table, nullColumnHack, initialValues, CONFLICT_REPLACE); 

太糟糕的文件不是很清楚。

SQLiteDatabase.replace()可能是你在找什么。 我没有尝试过,但医生说,它返回新插入行行ID ,所以它可能工作。

你需要确定你的表的列使它独特的行。

例如:_id,名字,工作,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; } 

在你的class级里:

 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)}); } 

我有同样的问题,但我意识到什么时候我的对象已经有一个Id它应该更新,当它没有一个Id它应该被插入,所以这是一步一步的,我做了什么来解决这个问题:

1-在你的对象getId使用整数或初始化你如何看待适合的ID:这是我的代码

 public Integer getId() { return id; } 

在将所有内容放入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是否存在我更新该行,但如果更新方法返回-1,这意味着没有该行的Id,所以我插入行,如果它没有一个Id我插入它。

希望这可以帮助。