【问题标题】:How to use "INSERT OR IGNORE" with "UPDATE" in Room database?如何在 Room 数据库中使用“INSERT OR IGNORE”和“UPDATE”?
【发布时间】:2020-05-12 20:29:58
【问题描述】:

如何在 Room 数据库中进行此查询?

@Query("INSERT OR IGNORE INTO ChapterInfo (chapterId, readDate) VALUES (:chapterId, :readDate) UPDATE ChapterInfo SET readDate = :readDate WHERE chapterId = :chapterId")
void insertReadChapterDate(long chapterId, Date readDate);

当我尝试这样做时,出现错误:“查询有问题:[SQLITE_ERROR] SQL 错误或缺少数据库(靠近“更新”:语法错误)”?

您知道如何将值插入到表中,但是如果具有此 ID 的记录存在 - 更新它?

【问题讨论】:

    标签: android-sqlite android-room


    【解决方案1】:

    也许通常的插入房间的方法可以吗?

    在你的道中:

    @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(ChapterInfo chapterInfo)

    调用你的 DAO 方法你的 put 对象(新的|修改的)作为参数。如果它的主键|键已经在 DB 中,Room 在表中创建行并替换行的字段。否则 Room 会添加新行。

    更新

    您的初始变体也可以修复(如果 chapterId - 是主键):

    @Query("INSERT OR REPLACE INTO ChapterInfo ('chapterId', 'readDate') VALUES (:chapterId, :readDate)
    void insertReadChapterDate(long chapterId, Date readDate);
    

    更新(2020 年 13 月 5 日)

    很明显,问题是关于: 如何在数据库中设置一些值,包括场景:

    1. 没有具有此类主键的行。然后函数应该添加新行,设置给定值,并且该行中的其余列不应该初始化
    2. 有这样的主键的行。然后函数应该只更新给定的值和其余的列 - 保持不变

    作为决定,您可以在一个事务中实现两个 SQL 命令“INSERT OR IGNORE”和“UPDATE”:

    @Query("INSERT OR IGNORE INTO ChapterInfo (chapterId, readDate) VALUES (:chapterId, :readDate) 
    void insertOrIgnoreChapterDate(long chapterId, Date readDate);
    
    @Query("UPDATE ChapterInfo SET readDate = :readDate WHERE chapterId = :chapterId)"
    void updateChapterDate(long chapterId, Date readDate);
    
    @Transaction
    void insertUpdateChapterDate(long chapterId, Date readDate){
        insertOrIgnoreChapterDate(long chapterId, Date readDate);
        updateChapterDate(long chapterId, Date readDate);
    }
    

    所以从外部你应该只使用“insertUpdateChapterDate”方法

    【讨论】:

    • 这不是一个好的解决方案,因为我可以在 raw 中有更多的值
    • 你能解释一下你的想法吗?
    • Table ChapterInfo [chapterId, readDate, otherData],我想在这个表中更新原始数据:“UPDATE ChapterInfo SET readDate = :readDate WHERE chapterId = :chapterId”但是当这个 chapterId 不存在原始数据时,我想要插入带有 chapterId 和 readDate 的新 raw
    • 好吧,我想我开始理解你了。您想告诉您,当您想调用您的方法“insertReadChapterDate”时,您只有“chapterId”和“readDate”,并且出于某种目的没有“otherData”。这就是为什么您要防止出现这种情况的原因,如果存在带有“chapterId”的行,则字段“otherData”将被覆盖并且您将丢失它。就这样?
    • 是的,这正是我想要的
    猜你喜欢
    • 2010-10-07
    • 2015-07-30
    • 2011-02-05
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多