android - 在冲突替换上创建唯一约束

标签 android sqlite

Android Studio 0.8.11

你好,

我在 FEED_NUMBER 列上有以下唯一约束。所以当我得到需要插入的新记录时,我将只替换具有相同 FEED_NUMBER 的记录。但是,当插入运行时,它总是添加新记录并忽略约束。我在这里做错了什么吗?

这是我的onCreate:

public void onCreate(SQLiteDatabase db) {
         String sql = "create table " + FottContract.TABLE
                + "(" + FottContract.Column.ID + " integer primary key autoincrement, "
                 + FottContract.Column.FEED_NUMBER + " text, "
                 + FottContract.Column.TITLE + " text, "
                 + FottContract.Column.DESCRIPTION + " text, "
                 + FottContract.Column.IMAGE + " text, "
                 + "unique (" + FottContract.Column.FEED_NUMBER + ") on conflict replace" + ")";

        db.execSQL(sql);
    }

这就是我插入的方式:

 private void saveToSQLite() {
        ContentValues contentValues = new ContentValues();

        /* For each item in the memory database insert into sqlite */
        for (int i = 0; i < mNewsFeedDB.size(); i++) {
            contentValues.put(FottContract.Column.FEED_NUMBER, mNewsFeedDB.get(i).getId());
            contentValues.put(FottContract.Column.TITLE, mNewsFeedDB.get(i).getTitle());
            contentValues.put(FottContract.Column.DESCRIPTION, mNewsFeedDB.get(i).getDescription());
            contentValues.put(FottContract.Column.IMAGE, mNewsFeedDB.get(i).getImage());

            /* Insert it */
            long row = mDb.insert(FottContract.TABLE, null, contentValues);
        }
    }

非常感谢您的任何建议,

最佳答案

编辑解决方案: 这个问题让我很恼火,所以我决定用与问题中相同的代码创建一个小测试项目。所以首先要注意的是 UNIQUE 约束得到了尊重。数据库中只有一行具有给定的 FeedNumber。但是,此行的 ID 会随着 UNIQUE 约束上的 ON CONFLICT REPLACE 计数(现有行被删除并替换为新行)和 ID 列上的 AUTOINCREMENT(将 ID 设置为最高 ID+1)的计数而改变。

其次,我尝试使用现有 ID 插入,当然失败了,因为您不能插入具有相同 PRIMARY ID 的两行。

因此解决方案是首先检查该行是否存在(尝试在 id 上插入),如果失败(即 row == -1),则改用 update 方法。这显然假设您实际上从 mNewsFeedDB.get(i).getId() 方法中获得了正确的行 ID。

Here is a link to my test project if anyone is interested in how I tested it.不是最漂亮的代码,但它可以完成工作。


我希望看到插入前后表格的打印,但是这行让我觉得有点可疑:

contentValues.put(FottContract.Column.FEED_NUMBER, mNewsFeedDB.get(i).getId());

您在这里所做的是获取给定 NewsFeedItem 的 ID 并将该值分配给 FEED_NUMBER 字段,但该 ID 真的与现有的 feedNumber 相同吗?如果 ID 为 null,例如 SQLite 会将每个 FEED_NUMBER 视为唯一的(因为不同的空值一起被视为不同的值)。

我之前遇到的另一件事是重用 ContentValues 对象。您可能需要为 for 循环中的每次传递创建一个新的 Contentvalues 对象。

关于android - 在冲突替换上创建唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26155454/

相关文章:

android - 添加页脚 View 后在回收站 View 中仅显示一项

Android HttpUrlConnection getInputStream 抛出 NullPointerException

要在 Ionic 4 中控制的 android 默认后退按钮

java - 如何存储通话记录

objective-c - 将文本字段中的数据插入 SQLite 数据库

android - 在 IntelliJ 13.0 中哪里可以找到 SQLite 的数据库面板?

android - 断开应用后 Google Drive Android API 仍然返回成功结果,但不上传文件

java - 将图库中的图片保存在我的外部 SD 文件夹中?

ruby-on-rails - Rails SQL 正则表达式

java - SQLite 连接和资源,良好实践