繁体   English   中英

如果我们有更多列,如何在房间数据库表中只插入 3 列数据?

[英]How to insert only 3 columns data in room database table if we have more columns?

我有一个在 kotlin 中编写的项目。 我想在不同页面上的同一个表的不同列中插入数据。 我已经在数据类中指定了这些列,但它给出了 null 数据错误。

为了让这个插入过程更健康,我应该把表分成两个单独的表还是发送 static 'null' 数据并更新这些字段?

在数据库中,例如 SQLite(Room 是一个包装器),插入单位是一行。

一行将由相同数量的列组成。 当更改反映在整个表中时,您不能单独插入列,除非您更改表以添加或删除列。

  • 如果添加列,则必须提供默认值,这可以是 null 的默认/隐式值或其他特定值。
  • 带有 Kotlin 的房间将应用 NOT NULL 的约束(规则),除非特别允许使用例如?
    • var theColumn: Int具有隐式 NOT NULL
    • var theColumn: Int? 没有隐式 NOT NULL 并且可以存储空值
    • var theColumn: Int=-1将在实例化 object 时在没有提供值的字段的情况下应用默认值 -1。
    • var theColumn: Int?=null将应用 null 在实例化 object 时没有提供值的字段。
      • 显然,如果使用 var 而不是 val,则在插入 object 之前可能会更改字段。

存储在列中的数据可以解释为代表任何你想要的,通常 NULL 会用于表示没有值等特殊情况。

如果使用带有@Insert注释的 function,则所有列都将应用从 object 或传递给 function 的对象中获得的值。 在 Kotlin 中是否可以使用 NULL 取决于字段定义或在某些情况下 @NonNull 注释。

@Insert表示所谓的便捷方法,它实际上构建底层 SQL 并使用 SQLite API 绑定值。

但是,如果您想要灵活性,则可以使用带有合适 INSERT SQL 语句的@Query注释。

例如,您可能有一个包含 4 列 COL1、COL2、COL3 和 COL4 的表,并且只应用一些列(如果指定,默认值将应用于另一列,如果不是 NULL 但如果存在 NOT NULL约束,则将引发冲突)。

因此,当只有两列(COL2 和 COL4)时插入,您可以使用:-

@Query("INSERT INTO theTable (COL2,COL4) VALUES(:valueForCol2,:valueForCol4)")
fun insertCol2AndCol4Only(valueForCol2: Int, valueForCol4: Int?)

请注意, valueForCol4可能是 NULL。 但是,NULL 是否会导致冲突取决于在 @Entity 注释的 class 中如何定义该字段。

SQLite 可以处理冲突(违反规则),具体取决于冲突的类型。 可以在 SQLite 级别以各种方式处理 UNIQUE、PRIMARY KEY(实际上是 UNIQUE 冲突)、CHECK(房间不满足 CHECK 约束)和 NOT NULL 约束。

冲突处理的一个常见用途是忽略冲突,在这种情况下,操作(INSERT 或 UPDATE)被忽略。 在 INSERT 的情况下,未插入行,但 SQLite 忽略冲突并且不发出错误。

因此,如果例如 COL4 的字段是var COL4: Int而不是var COL4: Int? 那么插入会失败,并且会发生 SQlite 异常。

但是,如果相反

@Query("INSERT OR IGNORE INTO theTable (COL2,COL4) VALUES(:valueForCol2,:valueForCol4)")

were used and the COL4 field were defined as var COL4: Int (implied NOT NULL constraint) then the conflict if NULL was passed as valueForCol4 then the row would not be inserted but no failure would occur as the NOT NULL conflict would be ignored.

使用@Insert注释,您可以通过 onConflictStrategy 参数定义此冲突处理,例如@Insert(onConflictStrategy=OnConflict.IGNORE)

您不妨考虑阅读以下内容:-

为了让这个插入过程更健康,我应该把表分成两个单独的表还是发送 static 'null' 数据并更新这些字段?

注意以上只是一个总结,INTEGER PRIMARY KEY aka @PrimaryKey var id: Long?=null或诸如@PrimaryKey(autoGenerate=true)等的变化没有具体讨论。

数据库的设计可以通过任何一种方式处理,从对场景的非常有限的描述来看,不能真正建议最可能合适的场景,尽管任何一种都可能是一种方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM